#!/usr/local/bin/cbsd
#v12.0.12
# TODO: became too complex, split into modules.
MYARG="dstdir jname media"
MYOPTARG="applytpl dstname efi freesize fromfile gw4 host_hostname inter ip4_addr label name nameserver nic nobase product prunelist publisher quiet swapsize timezone ver vm_guestfs \
mfsbsd_hostname mfsbsd_interface mfsbsd_vlan mfsbsd_defaultrouter mfsbsd_ip_addr mfsbsd_nameservers mfsbsd_origin_site mfs_struct_only extra_part extra_part_label"

MYDESC="Create bootable ISO/Memstick/MFSBSD image from CBSD jail"

ADDHELP="
Since the CBSD combines primitives for working with jail containers, virtual images and virtual machines, 
the function of creating an image from a container suggests itself. Create and setup your own LiveCD envoronment from
FreeBSD jail to build own distribution ( MFSBSD or cloud-init based instances );

Create bootable ISO/Memstick image from CBSD jail;

${H3_COLOR}Description${N0_COLOR}:

 Hint: use ~cbsd/jails-system/\$jname/loader.conf file to extra loader.conf entries.

${H3_COLOR}Options${N0_COLOR}:

 ${N2_COLOR}applytpl=${N0_COLOR}      - manage rc.conf for image, e.g set ip,hostname,nameserver. default - 1, apply;
 ${N2_COLOR}dstdir=${N0_COLOR}        - destination dir for storing jname.iso;
 ${N2_COLOR}dstname=${N0_COLOR}       - for alternative image name;
 ${N2_COLOR}efi=${N0_COLOR}           - set 0 to disable efi by default (if efiboot.img exist its preffered boot method);
 ${N2_COLOR}freesize=${N0_COLOR}      - reserved (expand to) X size of image free space (100m, 1g);
 ${N2_COLOR}fromfile=${N0_COLOR}      - Read arguments from file;
 ${N2_COLOR}gw4=${N0_COLOR}           - gateway for IPv4;
 ${N2_COLOR}host_hostname=${N0_COLOR} - set hostname in rc.conf image (freebsd only);
 ${N2_COLOR}ip4_addr=${N0_COLOR}      - set ip4 addr or 'DHCP' in rc.conf image (FreeBSD only);
 ${N2_COLOR}jname=${N0_COLOR}         - source data jail name;
 ${N2_COLOR}label=${N0_COLOR}         - label for media;
 ${N2_COLOR}media=${N0_COLOR}         - 'iso','memstick','livecd','bhyve' or 'mfs';
 ${N2_COLOR}name=${N0_COLOR}          - for alternative kernel name (GENERIC is default);
 ${N2_COLOR}nameserver=${N0_COLOR}    - set nameserver in image (freebsd only);
 ${N2_COLOR}nic=${N0_COLOR}           - specify network interface for ip4_addr, use 'auto' for 'ifconfig_DEFAULT=';
 ${N2_COLOR}prunelist=${N0_COLOR}     - path to prunelist, default is \${sharedir}/jail2iso-prunelist. 0 for disable;
 ${N2_COLOR}swapsize=${N0_COLOR}      - Allocate/configure SWAP partition to X size;
 ${N2_COLOR}timezone=${N0_COLOR}      - set timezone in image (freebsd only);
 ${N2_COLOR}vm_guestfs=${N0_COLOR}    - 'ufs' or 'zfs'. Default is: 'ufs';

${H3_COLOR}Options for 'media=mfs'${N0_COLOR}:

 ${N2_COLOR}mfsbsd_hostname${N0_COLOR}      - pass 'hostname' values to MFSBSD script;
 ${N2_COLOR}mfsbsd_interface${N0_COLOR}     - pass configured interace name to MFSBSD script, possible values:
                        - interface name, e.g.: 'vtnet0', 'xi0', 're1', 'igb2';
                        - when 'auto', ifconfig_DEFAULT will be used;
                        - when values sets to MAC (hwaddr), the interface will be found by MAC, e.g.: '58:9c:fc:10:45:5a';
 ${N2_COLOR}mfsbsd_vlan{N0_COLOR}           - VLAN ID or '0' for accessport/untagged;
 ${N2_COLOR}mfsbsd_defaultrouter${N0_COLOR} - pass 'defaultrouter'/'ipv6_defaultrouter' values to MFSBSD script, e.g.:
                        '10.0.0.1' or '2a05:3580:d811:802::1' or '10.0.0.1,2a05:3580:d811:802::1';
 ${N2_COLOR}mfsbsd_ip_addr${N0_COLOR}       - pass IPv4 and/or IPv6 values for 'mfsbsd_interface', e.g.: '10.0.0.2' or 
                        '2a05:3580:d811:802::2' or '10.0.0.2,2a05:3580:d811:802::2'. For DHCP use 'REALDHCP' values;
 ${N2_COLOR}mfsbsd_nameservers${N0_COLOR}   - pass 'nameserver' to MFSBSD script, e.g.: '8.8.8.8' or 
                        '9.9.9.9,149.112.112.112,2620:fe::fe,2620:fe::9';
 ${N2_COLOR}mfsbsd_origin_site${N0_COLOR}   - pass origin site for 'netkldload' script to MFSBSD script, e.g.: 'netboot.example.com';


${H3_COLOR}Examples${N0_COLOR}:

  # cbsd jail2iso jname=jail1 dstdir=/tmp media=mfs efi=1 mfsbsd_nameservers=8.8.8.8 mfsbsd_ip_addr=10.0.100.5 mfsbsd_defaultrouter=10.0.100.1 mfsbsd_interface=auto
  # cbsd jail2iso jname=jail1 dstdir=/tmp media=mfs efi=1 mfsbsd_nameservers=8.8.8.8 mfsbsd_ip_addr=REALDHCP mfsbsd_interface=auto
  # cbsd jail2iso jname=micro1 dstdir=/tmp media=bhyve freesize=4m efi=1 ver=native vm_guestfs=zfs
  # cbsd jail2iso jname=livecd dstdir=/tmp media=mfs efi=1 ver=native ip4_addr=172.16.0.40 gw4=172.16.0.1 nameserver=8.8.8.8
  # cbsd jail2iso jname=livecd dstdir=/tmp media=iso freesize=4m efi=1 ver=native

  Micro bhyve sample URL: https://github.com/cbsd/microbhyve

"
EXTHELP="wf_jail2iso"

. ${subrdir}/nc.subr

readconf buildworld.conf
readconf jail2iso.conf

# todo: to conf
EFI_PART_SIZE="260m"			# default FreeBSD efi partition

# MFS
MFSROOT_MAXSIZE="120m"
#MFSROOT_FREE_INODES="10%"
MFSROOT_FREE_INODES="1%"
#MFSROOT_FREE_BLOCKS?=  10%
MFSROOT_FREE_BLOCKS="1%"

applytpl=1
ver=
over=
name=
oname=
gw4=
ip4_addr=

mfsbsd_hostname=
mfsbsd_interface=
mfsbsd_vlan=
mfsbsd_defaultrouter=
mfsbsd_ip_addr=
mfsbsd_nameservers=
mfsbsd_origin_site=
mfs_struct_only=0

extra_part=
extra_part_label=
. ${cbsdinit}

if [ -z "${ver}" -o "${ver}" = "native" ]; then
	# ver=$( ${SYSCTL_CMD} -n kern.osrelease | ${CUT_CMD} -d - -f 1 )
	# we preffer uname as source, due to some environment have UNAME_r for overwrite version
	tmpver=$( ${UNAME_CMD} -r )
	ver=${tmpver%%-*}
	unset tmpver
	[ "${stable}" = "1" -a -z "${over}" ] && ver=${ver%%.*}
fi

[ -n "${extra_part}" -a ! -d "${extra_part}" ] && err 1 "${W1_COLOR}Warning: ${N1_COLOR}extra_part sets but direcory not exist: ${N2_COLOR}${extra_part}${N0_COLOR}"

over="${ver}"
[ -n "${name}" ] && oname="${name}"
if [ -z "${ip4_addr}" -a -n "${mfsbsd_ip_addr}" ]; then
	ip4_addr="${mfsbsd_ip_addr}"
fi
[ -n "${ip4_addr}" ] && oip4_addr="${ip4_addr}"
[ -n "${gw4}" ] && ogw4="${gw4}"

if [ -n "${mfsbsd_ip_addr}" -a -z "${mfsbsd_interface}" ]; then
	err 1 "${W1_COLOR}Warning: ${N1_COLOR}mfsbsd_ip_addr sets without ${N2_COLOR}mfsbsd_interface=${N0_COLOR}"
fi
[ -z "${mfsbsd_vlan}" ] && mfsbsd_vlan="0"

oapplytpl="${applytpl}"

. ${system}
. ${subrdir}/zfs.subr
. ${subrdir}/universe.subr
. ${subrdir}/bhyve.subr
. ${subrdir}/build.subr

. ${subrdir}/rcconf.subr
[ $? -eq 1 ] && err 1 "${N1_COLOR}no such jail: ${N2_COLOR}${jname}${N0_COLOR}"

# restore orig ver after rcconf
[ -n "${over}" ] && ver="${over}"

[ ${jid} -ne 0 ] && err 1 "${N1_COLOR}jail is active. please stop them first: ${N2_COLOR}${jname}${N0_COLOR}"

[ -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 "${N1_COLOR}For media=bhyve please set freesize= value. For example: ${N2_COLOR}freesize=1g${N0_COLOR}"

init_target_arch
init_srcdir
init_supported_arch

if [ -z "${ver}" -o "${ver}" = "native" ]; then
	# ver=$( ${SYSCTL_CMD} -n kern.osrelease | ${CUT_CMD} -d - -f 1 )
	# we preffer uname as source, due to some environment have UNAME_r for overwrite version
	tmpver=$( ${UNAME_CMD} -r )
	ver=${tmpver%%-*}
	unset tmpver
fi

if [ ${baserw} -ne 1 ]; then
	init_basedir
else
	nobase=1
	${ECHO} "${N1_COLOR}${CBSD_APP}: baserw=1, skip init_basedir: ${N2_COLOR}${jname}${N0_COLOR}"
fi

[ -n "${oname}" ] && name="${oname}"

init_kerneldir
${ECHO} "${N1_COLOR}${CBSD_APP}: KERNEL_DIR: ${N2_COLOR}${KERNEL_DIR}${N0_COLOR}"

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

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

TRAP=

clear_tmp_dir()
{
	[ "${mfs_struct_only}" = "1" ] && return 0
	if [ -d "${TMP_DIR}" -o -f "${TMP_DIR}" ]; then
		[ "${platform}" != "Linux" ] && nice -n 19 ${IDPRIO_CMD} 29 ${CHFLAGS_CMD} -R noschg ${TMP_DIR}
		${RM_CMD} -rf ${TMP_DIR}
	fi
}

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

	${CP_CMD} -rP ${path}/etc ${DST_DIR}/

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

	${CAT_CMD} > ${DST_DIR}${rcscript} <<EOF
#!/bin/sh
#
# Copyright (c) 2015-2024 CBSD Team

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

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

MOUNTOK=0
maxretry=10
retry=0

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

if [ ! -d /usr/bin ]; then
	MD=\$( ${MDCONFIG_CMD} -o readonly -a -t vnode -f /mnt/usr.uzip )
	${MOUNT_CMD} -oro /dev/\${MD}.uzip /mnt/usr
	${MOUNT_CMD} -oro -t nullfs /mnt/usr /usr
	${MOUNT_CMD} -oro -t nullfs /mnt/boot /boot
	hash -r
fi
EOF

	${CHMOD_CMD} 0555 ${DST_DIR}${rcscript}

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

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

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

	${ECHO} "${N1_COLOR}Prune file by list: ${N2_COLOR}${prunelist}${N0_COLOR}"

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

# $1 - rootdir
epilogue_img()
{
	local _rootfs="${1}"
	local _ret=

	[ -z "${_rootfs}" -a ! -d "${_rootfs}" ] && return 0
	[ "${nic}" = "auto" ] && nic="DEFAULT"

	${ECHO} "${N1_COLOR}Epilogue for ${N2_COLOR}${_rootfs}${N0_COLOR}"

	# for ISO too?
	[ "${media}" = "memstick" ] && return 0

	/usr/local/cbsd/misc/cbsdsysrc -qf ${_rootfs}/etc/rc.conf fsck_y_enable="YES" >/dev/null

	# MFS override?
	[ -n "${host_hostname}" ] && /usr/local/cbsd/misc/cbsdsysrc -qf ${_rootfs}/etc/rc.conf hostname="${host_hostname}" >/dev/null
	[ -n "${oip4_addr}" ] && ip4_addr="${oip4_addr}"
	[ -n "${ogw4}" ] && gw4="${ogw4}"
	[ -z "${nic}" ] && nic="DEFAULT"

	if [ "${media}" != "mfs" ]; then
		${GREP_CMD} -q ^ifconfig_${nic}= ${_rootfs}/etc/rc.conf
		_ret=$?
		if [ ${_ret} -ne 0 ]; then
			if [ -n "${ip4_addr}" -a "${ip4_addr}" != "0" ]; then
				case "${ip4_addr}" in
					[Dd][Hh][Cc][Pp])
						/usr/local/cbsd/misc/cbsdsysrc -qf ${_rootfs}/etc/rc.conf ifconfig_${nic}="DHCP" >/dev/null
						;;
					*)
						/usr/local/cbsd/misc/cbsdsysrc -qf ${_rootfs}/etc/rc.conf ifconfig_${nic}="inet ${ip4_addr}" >/dev/null
						;;
				esac
			fi
		fi
	else
		/usr/local/cbsd/misc/cbsdsysrc -qf ${_rootfs}/etc/rc.conf mfsbsd_enable="YES"

	fi

#		case "${mfsbsd_interface}" in
#			auto)
#				true
#				;;
#			*)
#				# is_mac?
#				if validate_hwaddr "${mfsbsd_interface}"; then
#					mfsbsd_mac_boot="${mfsbsd_interface}"
#					# force mfs_interface to any value, e.g.: 'auto'
#					mfsbsd_interface="auto"
#				fi
#				;;
#		esac
#	fi

	if [ -z "${mfsbsd_defaultrouter}" ]; then
		[ -n "${gw4}" ] && /usr/local/cbsd/misc/cbsdsysrc -qf ${_rootfs}/etc/rc.conf defaultrouter="${gw4}" >/dev/null
	fi

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

	if [ -n "${timezone}" ]; then
		[ -f "/usr/share/zoneinfo/${timezone}" ] && ${CP_CMD} /usr/share/zoneinfo/${timezone} ${_rootfs}/etc/localtime
	fi

	${ECHO} "${N1_COLOR}${CBSD_APP}: epilogue ${N2_COLOR}/etc/rc.conf:${N0_COLOR}"
	${CAT_CMD} ${_rootfs}/etc/rc.conf
}


makemfsroot()
{
	local _filelist _ver
	local _tmpdir=$( ${MKTEMP_CMD} -d )

	if [ "${media}" = "mfs" ]; then
		installworld destdir=${_tmpdir} ver=${ver}
		[ ! -d ${_tmpdir}/boot/kernel ] && ${MKDIR_CMD} ${_tmpdir}/boot/kernel
		${CP_CMD} -a ${KERNEL_DIR}/boot/kernel/*.ko ${_tmpdir}/boot/kernel/
		#${MAKEFS_CMD} -t ffs -m ${MFSROOT_MAXSIZE} -f ${MFSROOT_FREE_INODES} -b ${MFSROOT_FREE_BLOCKS} ${WRKDIR}/disk/mfsroot ${_ROOTDIR}
		${CAT_CMD} >> ${_tmpdir}/boot/loader.conf << EOF
hw.efi.poweroff=0
mfs_load="YES"
mfs_type="mfs_root"
mfs_name="/mfsroot"
vfs.root.mountfrom="ufs:/dev/md0"
autoboot_delay="-1"
net.inet.ip.fw.default_to_accept="1"
vm.pmap.pti="0"
hw.ibrs_disable="1"
debug.acpi.disabled="thermal"
hw.usb.no_shutdown_wait="1"
hw.mfi.mrsas_enable="1"
hw.usb.no_pf="1"
hw.igb.rx_process_limit="-1"
hw.em.rx_process_limit="-1"
hw.ix.rx_process_limit="-1"
EOF

		[ ! -d ${TMP_DIR} ] && ${MKDIR_CMD} -p ${TMP_DIR}
		${MAKEFS_CMD} -t ffs ${TMP_DIR}/mfsroot ${_tmpdir}
		${GZIP_CMD} -9 ${TMP_DIR}/mfsroot
		return 0
	fi

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

	_ver=${ver%%.*}

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

	[ ! -r ${_filelist} ] && err 1 "${N1_COLOR}${CBSD_APP}: no such index file: ${N2_COLOR}${_filelist}${N0_COLOR}"

	${ECHO} "${N1_COLOR}mfsroot index: ${N2_COLOR}${_filelist}${N0_COLOR}"

	if [ -z "${BASE_DIR}" ]; then
		# get BASE_DIR
		# todo: nobase=1 and baserw=1 ???
		init_basedir
	fi

	[ -z "${BASE_DIR}" ] && err 1 "${N1_COLOR}${CBSD_APP} empty BASE_DIR${N0_COLOR}"

	#echo "copy-binlib filelist=${_filelist} dstdir=${_tmpdir} basedir=${BASE_DIR} chaselibs=1 mtree=1"
	copy-binlib filelist=${_filelist} dstdir=${_tmpdir} basedir=${BASE_DIR} chaselibs=1 mtree=1

	preparebase dst=${_tmpdir}

	local _size=0

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

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

#	echo "$_size"

	# NOT REL
	_size=80000
#	_size=230000

	# Linux does not support postfix in bs=, e.g. bs=1k
	case "${platform}" in
		Linux)
			${DD_CMD} if=/dev/zero of=${mfsrootfile} count=${_size} bs=1024000
			;;
		*)
			${DD_CMD} if=/dev/zero of=${mfsrootfile} count=${_size} bs=1k
			;;
	esac
	DEV=$( ${MDCONFIG_CMD} -a -t vnode -f ${mfsrootfile} )
	${BSDLABEL_CMD} -w /dev/${DEV} auto
	nice -n 19 ${IDPRIO_CMD} 29 ${NEWFS_CMD} -n -i ${BS} -m 0 -o space /dev/${DEV}
	${MKDIR_CMD} -p ${DST_DIR}
	${MOUNT_CMD} /dev/${DEV} ${DST_DIR}
	cd ${_tmpdir} && nice -n 19 ${IDPRIO_CMD} 29 ${FIND_CMD} -E ${_tmpdir} -mindepth 1 \( -type f -or -type d -or -type l \) -print | ${SED_CMD} s:${_tmpdir}:./:g | nice -n 19 ${IDPRIO_CMD} 29 ${CPIO_CMD} -pdmu ${DST_DIR}

	[ "${platform}" != "Linux" ] &&  nice -n 19 ${IDPRIO_CMD} 29 ${CHFLAGS_CMD}  -R noschg ${_tmpdir}
	${RM_CMD} -rf ${_tmpdir}
	prepare_dir
	[ "${prunelist}" != "0" ] && prunelist ${DST_DIR}
	cd /
	# make flags for preparedir script
	[ -d "${DST_DIR}/usr/bin" ] && ${RM_CMD} -rf ${DST_DIR}/usr/bin
	${UMOUNT_CMD} -f ${DST_DIR} && ${RMDIR_CMD} ${DST_DIR}
	${MDCONFIG_CMD} -d -u ${DEV}

	${ECHO} "${N1_COLOR}${CBSD_APP} mfsroot done, temp md: ${N2_COLOR}${DEV}${N0_COLOR}" 1>&2
}


show_bhyve_message()
{
	if [ ${freebsdhostversion} -lt 1300021 ]; then
		local _tap_module="if_tap"
	else
		local _tap_module="if_tuntap"
	fi

	$ECHO "${N1_COLOR}Completed. Image ready for bhyve, example:${N0_COLOR}"
	${CAT_CMD} << EOF
 % kldload vmm
 % kldload ${_tap_module}
 % sysctl -w net.link.tap.up_on_open=1
 % ifconfig tap0 create
 % ifconfig bridge0 create
EOF
    ${ECHO} " % ifconfig bridge0 addm ${mynic} addm tap0    ${N2_COLOR}<< -- where ${mynic} is uplink${N0_COLOR}"
    ${CAT_CMD} << EOF
 % ifconfig bridge0 up
 % sh /usr/share/examples/bhyve/vmrun.sh -d ${dstdir}/${dstname} -m1g ${jname}
EOF
}

# $1 - source dir
# $2 - dst file image
create_img_for_dir()
{
	local base_size minfree1 minfree2
	local _res _msg
	local _reserved_size="512m"		# free reserved size
	local _efi_size="${EFI_PART_SIZE}"

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

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

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

	if [ -d "${1}" ]; then
		base_size=$( ${DU_CMD} -sk ${1} | ${AWK_CMD} '{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 + _reserved_size + _efi_size ))
	#fs_size=$(( base_size + freesize + minfree1 + minfree2 ))
	# ?? recalc
	fs_size="${freesize}"

	if conv2human "${all_size}"; then
		all_size=${convval}
	fi

	echo "r: ${_reserved_size} , e: ${_efi_size} "
	echo "virtual_create_dsk -p ${2} -s ${all_size} -f 0 -t md"

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


bhyve_zfs_install()
{
	local mnttmp tmpjname
	local _ret
	${KLDSTAT_CMD} -qm zfs || ${KLDLOAD_CMD} zfs
	mnttmp=$( ${MKTEMP_CMD} -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
		${ZPOOL_CMD} get -Ho value guid ${mypool} > /dev/null 2>&1
		[ $? -ne 0 ] && 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 "${N1_COLOR}Can't find free pool name: ${N2_COLOR}${mypool}${N0_COLOR}"

	if [ "${baserw}" = "0" ]; then
		mountbase -o "" -p "" -d "" -c "" -s ""
		if  [ "${ver}" != "empty" ]; then
				[ -f "${mount_fstab}" ] && mountfstab jroot=${path} fstab=${mount_fstab} jname="${jname}" > /dev/null 2>&1
				[ -f "${mount_fstab}.local" ] && mountfstab jroot=${path} fstab=${mount_fstab}.local jname="${jname}" > /dev/null 2>&1
		fi
	fi

	if [ ${baserw} -eq 1 ]; then
		srcdata=${data}
	else
		srcdata=${path}
	fi
	echo "zfsinstall devs=${unit} ver=${ver} arch=${arch} srcdata=${srcdata} mnt=${mnttmp} pool=${mypool} swap=\"${swapsize}\" quiet=1"
	zfsinstall devs=${unit} ver=${ver} arch=${arch} srcdata=${srcdata} mnt=${mnttmp} pool=${mypool} swap="${swapsize}" quiet=1
	_ret=$?
	echo "RET ${_ret}"
	[ ${_ret} -ne 0 ] && err 1 "${N1_COLOR}jail2iso: zfsinstall error${N0_COLOR}"

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

# detect for swap
FSWAP=\$( ${GPART_CMD} list | ${GREP_CMD} -B50 "type: freebsd-swap" | ${GREP_CMD} Name: | ${TAIL_CMD} -n1 |${AWK_CMD} '/Name:/{print \$3}' )

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

${RM_CMD} -f /etc/rc.local
EOF
	[ ${oapplytpl} -eq 1 ] && epilogue_img ${mnttmp}

	post_module_action ${mnttmp}

	${UMOUNT_CMD} ${mnttmp}/var > /dev/null 2>&1
	${UMOUNT_CMD} ${mnttmp}/tmp > /dev/null 2>&1
	${UMOUNT_CMD} ${mnttmp} > /dev/null 2>&1
	${RMDIR_CMD} ${mnttmp} > /dev/null 2>&1
	${ZPOOL_CMD} export -f ${mypool}
}

check_for_external_mount()
{
	local _i _checkpath="${path}/usr/ports/distfiles ${path}/usr/ports/packages ${path}/usr/src ${path}/usr/obj ${path}/usr/ports ${path}/usr/src"

	for _i in ${_checkpath}; do
		if is_mounted ${_i}; then
			if getyesno "${N1_COLOR}external mount: ${N2_COLOR}${_i}${N1_COLOR}, unmount first?${N0_COLOR}"; then
				${UMOUNT_CMD} -f ${_i}
			fi
		fi
	done
}

# Create full FS/data hier in ${TMP_DIR} directory
# for MFS: ${TMP_DIR}/root - directory for LiveCD
make_ufs()
{
	local _init_bin
	local _ncpu=

	${ECHO} "${N1_COLOR}kernel required ver: ${ver}${N0_COLOR}" 1>&2
	# move to kernel init?
	get_kernel
	[ ! -d "${KERNEL_DIR}" ] && err 1 "No such ${KERNEL_DIR}"

	case "${media}" in
		iso|memstick|bhyve|livecd|mfs)
			;;
		*)
			err 1 "${N1_COLOR}unknown media type. must be: ${N2_COLOR}iso${N1_COLOR},${N2_COLOR}memstick${N1_COLOR},${N2_COLOR}livecd ${N1_COLOR}or${N2_COLOR} bhyve${N0_COLOR}"
			;;
	esac

	mountbase -o "" -p "" -d "" -c "" -s ""

	if  [ "${ver}" != "empty" ]; then
		if [ "${baserw}" = "0" ]; then
			[ -r "${mount_fstab}" ] && mountfstab jroot=${path} fstab=${mount_fstab} jname="${jname}" > /dev/null 2>&1
			[ -r "${mount_fstab}.local" ] && mountfstab jroot=${path} fstab=${mount_fstab}.local jname="${jname}" > /dev/null 2>&1
		fi
	fi

	check_for_external_mount

	BS=8192
	case "${media}" in
		bhyve|livecd|mfs)
			;;
		*)
			makemfsroot
			;;
	esac

	TRAP="${TRAP} clear_tmp_dir;"
	trap "${TRAP}" HUP INT ABRT BUS TERM EXIT
	${MKDIR_CMD} -p ${TMP_DIR}
	# store orig TMP_DIR for MFS: we build 'rw' part for MFS here
	if [ "${media}" = "mfs" ]; then
		OTMP_DIR="${TMP_DIR}"
		TMP_DIR="${OTMP_DIR}/rw"
		${MKDIR_CMD} -p ${TMP_DIR}
		${RSYNC_CMD} -avz --links ${path}/ ${TMP_DIR}/
	fi

	#echo "[debug] cd ${path} && nice -n 19 ${IDPRIO_CMD} 29 ${PAX_CMD} -p eme -rw . ${TMP_DIR}"

	${ECHO} "${N1_COLOR}${CBSD_APP}: make_ufs: media: ${N2_COLOR}${media}${N0_COLOR}"

	if [ "${media}" != "mfs" ]; then
		echo "[debug]cd ${path} && nice -n 19 ${IDPRIO_CMD} 29 ${PAX_CMD} -p eme -rw . ${TMP_DIR}" 1>&2
		cd ${path} && nice -n 19 ${IDPRIO_CMD} 29 ${PAX_CMD} -p eme -rw . ${TMP_DIR}
		sync
	else
		# not for MFS
		[ -d "${TMP_DIR}/boot" ] && ${RM_CMD} -rf ${TMP_DIR}/boot
		${CP_CMD} -a ${path}/boot ${TMP_DIR}/
		${RM_CMD} -rf ${TMP_DIR}/boot/kernel
	fi

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

	# remove archive
	# BAD FOR packages
	#[ "${media}" != "bhyve" ] && ${FIND_CMD} ${TMP_DIR} -mindepth 1 -type f -name \*.a -delete

	[ ! -d ${TMP_DIR}/boot/kernel ] && ${MKDIR_CMD} -p ${TMP_DIR}/boot/kernel

	if [ "${media}" != "mfs" ]; then
		${CP_CMD} -a ${KERNEL_DIR}/boot/kernel/* ${TMP_DIR}/boot/kernel/
		if [ ! -r "${TMP_DIR}/boot/kernel/kernel" -a ! -r "${TMP_DIR}/boot/kernel/kernel.gz" ]; then
			echo "no such ${TMP_DIR}/boot/kernel/kernel"
			echo "check: ${CP_CMD} -a ${KERNEL_DIR}/boot/kernel/* ${TMP_DIR}/boot/kernel/"
		fi

		if [ "${media}" != "bhyve" ]; then
			${RM_CMD} -f ${TMP_DIR}/boot/kernel/*.symbols
			if [ -r "${TMP_DIR}/boot/kernel/kernel" ]; then
				cd ${TMP_DIR}/boot/kernel && ${GZIP_CMD} -9 ./kernel
			fi
		fi

		if [ -r "${jailsysdir}/${jname}/loader.conf" ]; then
			${ECHO} "${N1_COLOR}${CBSD_APP}: custom loader.conf found: ${N2_COLOR}${jailsysdir}/${jname}/loader.conf${N0_COLOR}"
			${CP_CMD} ${jailsysdir}/${jname}/loader.conf ${TMP_DIR}/boot/loader.conf
		else
			${ECHO} "${N1_COLOR}${CBSD_APP}: custom loader.conf absent in ${jailsysdir}/${jname}/loader.conf${N0_COLOR}"
		fi
	fi


	case "${media}" in
		bhyve)
			ROOTFS="/dev/ufs/${LABEL} / ufs rw,noatime 1 1"
			${CAT_CMD} >> ${TMP_DIR}/boot/loader.conf <<EOF
# jail2iso
console="userboot"
hw.efi.poweroff=0
EOF
			${CAT_CMD} > ${TMP_DIR}/etc/fstab <<EOF
${ROOTFS}
EOF
			;;
		livecd)
			ROOTFS="/dev/iso9660/${LABEL} /mnt cd9660 ro 0 0"
${CAT_CMD} >> ${TMP_DIR}/boot/loader.conf <<EOF
# jail2iso
console="userboot"
vfs.root.mountfrom="cd9660:/dev/iso9660/${LABEL}"
hw.efi.poweroff=0
EOF
# $ROOTFS in /etc/fstab not mandatory, already mounted? 
# unionfs for /etc/?
			${CAT_CMD} > ${TMP_DIR}/etc/fstab << EOF
tmpfs /tmp tmpfs rw 0 0
tmpfs /var/run tmpfs rw 0 0
tmpfs /boot/zfs tmpfs rw 0 0
EOF
			;;
		iso)
			ROOTFS="/dev/iso9660/${LABEL} /mnt cd9660 ro 0 0"
			${CAT_CMD} >> ${TMP_DIR}/boot/loader.conf << EOF
hw.efi.poweroff=0
#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
			${CAT_CMD} > ${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
			;;
		memstick)
			ROOTFS="/dev/ufs/${LABEL} /mnt ufs ro,noatime 1 1"
			${CAT_CMD} >> ${TMP_DIR}/boot/loader.conf << EOF
hw.efi.poweroff=0
#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
			${CAT_CMD} > ${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
			;;
		mfs)
			;;
	esac

	if [ "${media}" != "mfs" ]; then
		if [ "${swapsize}" != "0" ]; then
			${CAT_CMD} >> ${TMP_DIR}/etc/fstab <<EOF
/dev/gpt/swap	none	swap	sw	0	0
EOF
		fi

		if [ -r "${jailsysdir}/${jname}/fstab" ]; then
			${ECHO} "${N1_COLOR}Extra fstab found: ${N2_COLOR}${jailsysdir}/${jname}/fstab${N0_COLOR}"
			${CAT_CMD} ${jailsysdir}/${jname}/fstab
			${CAT_CMD} ${jailsysdir}/${jname}/fstab >> ${TMP_DIR}/etc/fstab
		fi

		[ ${oapplytpl} -eq 1 ] && echo "Welcome to ${PRODUCT}" > ${TMP_DIR}/etc/motd

		case "${media}" in
			bhyve|livecd)
				${CAT_CMD} > ${TMP_DIR}/etc/ttys <<EOF
console "/usr/libexec/getty std.9600"   vt100   on secure
EOF
				;;
			*)
				${MV_CMD} ${mfsrootfile} ${TMP_DIR}/mfsroot
				cd ${TMP_DIR}
				nice -n 19 ${IDPRIO_CMD} 29 ${GZIP_CMD} -9 ${TMP_DIR}/mfsroot
				TRAP="${TRAP} ${RM_CMD} -f ${tmpdir}/usr.img.$$ ;"
				trap "${TRAP}" HUP INT ABRT BUS TERM EXIT
				nice -n 19 ${IDPRIO_CMD} 29 ${MAKEFS_CMD} -o optimization=space -t ffs ${tmpdir}/usr.img.$$ ${TMP_DIR}/usr
				nice -n 19 ${IDPRIO_CMD} 29 ${MKUZIP_CMD} -o ${TMP_DIR}/usr.uzip ${tmpdir}/usr.img.$$
				[ "${platform}" != "Linux" ] && ${CHFLAGS_CMD} -R noschg ${TMP_DIR}/usr
				${RM_CMD} -rf ${TMP_DIR}/usr && ${MKDIR_CMD} ${TMP_DIR}/usr
				# LiveCD location
				[ -f "${jailsysdir}/${jname}/tmpfsdir" ] && ${CP_CMD} ${jailsysdir}/${jname}/tmpfsdir ${TMP_DIR}/etc/
				;;
		esac

		# post action inside image
		[ ${oapplytpl} -eq 1 ] && epilogue_img ${TMP_DIR}
	else
		# for MFS, TMP_DIR is 'rw' directory, last layer
		#${MV_CMD} ${mfsrootfile} ${TMP_DIR}/mfsroot
		# post action inside image
		[ ${oapplytpl} -eq 1 ] && epilogue_img ${TMP_DIR}
		cd ${OTMP_DIR}
		nice -n 19 ${IDPRIO_CMD} 29 ${TAR_CMD} cf rw.tar rw

		# inherit from inventory?
		case "${platform}" in
			Linux)
				_ncpu=$( ${GREP_CMD} -E "^vendor_id" /proc/cpuinfo | ${WC_CMD} -l )
				;;
			*)
				_ncpu=$( ${SYSCTL_CMD} -n hw.ncpu 2>/dev/null )
				;;
		esac

		[ -z "${_ncpu}" ] && _ncpu="1"
		nice -n 19 ${IDPRIO_CMD} 29 ${XZ_CMD} -T${_ncpu} -v -c rw.tar > root.txz
		_ret=$?
		${RM_CMD} -f rw.tar
		[ ${_ret} -ne 0 ] && err 1 "${N1_COLOR}${CBSD_APP}: make_ufs error for mfs: ${N2_COLOR}${XZ_CMD} -T${_ncpu} -v -c rw.tar > root.txz${N0_COLOR}"
		${RM_CMD} -rf ${TMP_DIR}
		TMP_DIR="${OTMP_DIR}"

		# create first MFS layer hier
		${MKDIR_CMD} -p ${TMP_DIR}/mfsroot1/boot/modules \
			${TMP_DIR}/mfsroot1/dev \
			${TMP_DIR}/mfsroot1/rw \
			${TMP_DIR}/mfsroot1/sbin \
			${TMP_DIR}/mfsroot1/usr/lib/debug/boot/kernel
		${MV_CMD} ${TMP_DIR}/root.txz ${TMP_DIR}/mfsroot1/root.txz

		# merge custom loader.conf
		if [ -r "${jailsysdir}/${jname}/loader.conf" ]; then
			${CAT_CMD} "${jailsysdir}/${jname}/loader.conf" > ${TMP_DIR}/mfsroot1/boot/loader.conf
		else
			${CAT_CMD} > ${TMP_DIR}/mfsroot1/boot/loader.conf <<EOF
aesni_load="YES"
ahci_load="YES"
autoboot_delay="-1"
#autoboot_delay="30"

cpuctl_load="YES"
debug.acpi.disabled="thermal"
hw.efi.poweroff="0"
hw.em.rx_process_limit="-1"
hw.ibrs_disable="1"
hw.igb.rx_process_limit="-1"
hw.ix.rx_process_limit="-1"
hw.mfi.mrsas_enable="1"
hw.usb.no_pf="1"
hw.usb.no_shutdown_wait="1"
ipfw_load="YES"

#
if_re_load="YES"
if_bnxt_load="YES"
if_qlnxe_load="YES"

net.inet.ip.fw.default_to_accept="1"
net.isr.maxqlimit="1000000"
net.link.ifqmaxlen="16384"

opensolaris_load="YES"
zfs_load="YES"
geom_concat_load="YES"
geom_eli_load="YES"
geom_gate_load="YES"
geom_journal_load="YES"
geom_mirror_load="YES"
geom_part_bsd64_load="YES"
geom_part_bsd_load="YES"
geom_part_mbr_load="YES"
vm.pmap.pti="0"

vfs.mountroot.timeout=3
EOF
		fi
${CAT_CMD} >> ${TMP_DIR}/mfsroot1/boot/loader.conf <<EOF
# CUSTOM MFS
mfs_load="YES"
mfs_name="/mfsroot"
mfs_type="mfs_root"
#mfsbsd.autodhcp="YES"
vfs.root.mountfrom="ufs:/dev/md0"
vfs.root_mount_always_wait=1
if_bridge_load="YES"
#pptdevs="0/2/0"
#vmm_load="YES"
geom_label_load="YES"
geom_md_load="YES"
geom_part_gpt_load="YES"
geom_uzip_load="YES"
EOF
		${CP_CMD} -a ${KERNEL_DIR}/boot/kernel/tmpfs.ko ${TMP_DIR}/mfsroot1/boot/modules/

		# ROOTHACK
		${CP_CMD} -a ${distdir}/modules/roothack.d/init ${TMP_DIR}/mfsroot1/sbin/init
		${ECHO} "${N1_COLOR}${CBSD_APP}: MFS: * ${N2_COLOR}Create first layer${N0_COLOR}"
		echo "${MAKEFS_CMD} -t ffs -f ${MFSROOT_FREE_INODES} -b ${MFSROOT_FREE_BLOCKS} mfsroot ${TMP_DIR}/mfsroot1"
		#pwd

		#${MAKEFS_CMD} -t ffs -m ${MFSROOT_MAXSIZE} -f ${MFSROOT_FREE_INODES} -b ${MFSROOT_FREE_BLOCKS} mfsroot ${TMP_DIR}/mfsroot1

		${MAKEFS_CMD} -t ffs -f ${MFSROOT_FREE_INODES} -b ${MFSROOT_FREE_BLOCKS} mfsroot ${TMP_DIR}/mfsroot1
		[ "${platform}" != "Linux" ] && ${CHFLAGS_CMD} -R noschg ${TMP_DIR}/mfsroot1
		${RM_CMD} -rf ${TMP_DIR}/mfsroot1
		${GZIP_CMD} -9 mfsroot

		# ZERO layer
		${MKDIR_CMD} -p ${TMP_DIR}/root
		${CAT_CMD} > ${TMP_DIR}/root/boot.config <<EOF
-D
EOF
		${MKDIR_CMD} -p ${TMP_DIR}/root/boot/defaults \
			${TMP_DIR}/root/boot/kernel \
			${TMP_DIR}/root/boot/lua

		# LUA
MFS_LUA_SCR="\
cli.lua \
color.lua \
config.lua \
core.lua \
drawer.lua \
gfx-beastie.lua \
gfx-beastiebw.lua \
gfx-fbsdbw.lua \
gfx-orb.lua \
gfx-orbbw.lua \
hook.lua \
loader.lua \
menu.lua \
password.lua \
screen.lua \
"
		for i in ${MFS_LUA_SCR}; do
			${CP_CMD} -a ${path}/boot/lua/${i} ${TMP_DIR}/root/boot/lua/${i}
		done

		${CP_CMD} -a ${path}/boot/defaults/loader.conf ${TMP_DIR}/root/boot/defaults/loader.conf

MFS_KERNEL_FILES="\
acpi_asus.ko \
acpi_asus_wmi.ko \
acpi_dock.ko \
acpi_fujitsu.ko \
acpi_hp.ko \
acpi_ibm.ko \
acpi_panasonic.ko \
acpi_sony.ko \
acpi_toshiba.ko \
acpi_video.ko \
acpi_wmi.ko \
ahci.ko \
aesni.ko \
if_qlnxe.ko \
if_bnxt.ko \
if_re.ko \
opensolaris.ko \
zfs.ko \
vmm.ko \
if_bridge.ko \
geom_concat.ko \
geom_eli.ko \
geom_gate.ko \
geom_journal.ko \
geom_label.ko \
geom_md.ko \
geom_mirror.ko \
geom_part_gpt.ko \
geom_part_bsd64.ko \
geom_part_bsd.ko \
geom_part_mbr.ko \
geom_uzip.ko \
snp.ko \
kernel \
kernel.gz \
linker.hints \
"
		# FIRMWARE
MFS_KERNEL_FILES="${MFS_KERNEL_FILES} \
accf_data.ko \
accf_dns.ko \
accf_http.ko \
cc_htcp.ko \
coretemp.ko \
cpu_microcode.ko \
cpuctl.ko \
cryptodev.ko \
ipfw.ko \
ipfw_nat.ko \
libalias.ko \
pf.ko \
sem.ko \
vmm.ko \
"


		for i in ${MFS_KERNEL_FILES}; do
			${CP_CMD} -a ${KERNEL_DIR}/boot/kernel/${i} ${TMP_DIR}/root/boot/kernel/${i}
		done

#		if [ -r "${TMP_DIR}/root/boot/kernel/kernel" ]; then
#			cd ${TMP_DIR}/root/boot/kernel/
#			${GZIP_CMD} -9 kernel
#		fi
		cd ${TMP_DIR}/

# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
MFS_BOOT_FILES="\
boot1.efi \
cdboot \
device.hints \
gptboot \
gptboot.efi \
loader \
loader.efi \
pmbr \
"

		for i in ${MFS_BOOT_FILES}; do
			${CP_CMD} -a ${path}/boot/${i} ${TMP_DIR}/root/boot/${i}
		done

		# merge custom loader.conf
		if [ -r "${jailsysdir}/${jname}/loader.conf" ]; then
			echo "# CDBOOT" > ${TMP_DIR}/root/boot/loader.conf
			${CAT_CMD} "${jailsysdir}/${jname}/loader.conf" >> ${TMP_DIR}/root/boot/loader.conf
		else
			${CAT_CMD} > ${TMP_DIR}/root/boot/loader.conf <<EOF
# CDBOOT
aesni_load="YES"
ahci_load="YES"

autoboot_delay="-1"
#autoboot_delay="10"

cpuctl_load="YES"
debug.acpi.disabled="thermal"
hw.efi.poweroff="0"
hw.em.rx_process_limit="-1"
hw.ibrs_disable="1"
hw.igb.rx_process_limit="-1"
hw.ix.rx_process_limit="-1"
hw.mfi.mrsas_enable="1"
hw.usb.no_pf="1"
hw.usb.no_shutdown_wait="1"
ipfw_load="YES"

#
if_re_load="YES"
if_bnxt_load="YES"
if_qlnxe_load="YES"

opensolaris_load="YES"
zfs_load="YES"
geom_concat_load="YES"
geom_eli_load="YES"
geom_gate_load="YES"
geom_journal_load="YES"
geom_label_load="YES"
geom_md_load="YES"
geom_mirror_load="YES"
geom_part_gpt_load="YES"
geom_part_bsd64_load="YES"
geom_part_bsd_load="YES"
geom_part_mbr_load="YES"
geom_uzip_load="YES"
net.inet.ip.fw.default_to_accept="1"
net.isr.maxqlimit="1000000"
net.link.ifqmaxlen="16384"
vfs.mountroot.timeout=3
vm.pmap.pti="0"
EOF
		fi
		${CAT_CMD} >> ${TMP_DIR}/root/boot/loader.conf <<EOF
# MFS
mfs_load="YES"
mfs_name="/mfsroot"
mfs_type="mfs_root"
vfs.root.mountfrom="ufs:/dev/md0"
vfs.root_mount_always_wait=1
if_bridge_load="YES"
#pptdevs="0/2/0"
#vmm_load="YES"
EOF

		${MV_CMD} ${TMP_DIR}/mfsroot.gz ${TMP_DIR}/root
	fi

	#
	[ ! -d ${TMP_DIR}/root/boot ] && ${MKDIR_CMD} ${TMP_DIR}/root/boot

	case "${mfsbsd_interface}" in
		auto)
			true
			;;
		*)
			# is_mac?
			if validate_hwaddr "${mfsbsd_interface}"; then
				mfsbsd_mac_boot="${mfsbsd_interface}"
				# force mfs_interface to any value, e.g.: 'auto'
				mfsbsd_interface="auto"
			fi
			;;
	esac

	echo "#__MFS_START_DATA=1" >> ${TMP_DIR}/root/boot/loader.conf
	if [ -n "${mfsbsd_hostname}" ]; then
		echo "mfsbsd.hostname=\"${mfsbsd_hostname}\"" >> ${TMP_DIR}/root/boot/loader.conf
	else
		echo "mfsbsd.hostname=\"\" ####################TPL#######################" >> ${TMP_DIR}/root/boot/loader.conf
	fi
	if [ -n "${mfsbsd_interface}" ]; then
		echo "mfsbsd.interface=\"${mfsbsd_interface}\"" >> ${TMP_DIR}/root/boot/loader.conf
	else
		echo "mfsbsd.interface=\"\" ##################TPL#########################" >> ${TMP_DIR}/root/boot/loader.conf
	fi
	if [ -n "${mfsbsd_vlan}" -a "${mfsbsd_vlan}" != "0" ]; then
		echo "mfsbsd.vlan=\"${mfsbsd_vlan}\"" >> ${TMP_DIR}/root/boot/loader.conf
	else
		echo "mfsbsd.vlan=\"\" ##################TPL#########################" >> ${TMP_DIR}/root/boot/loader.conf
	fi
	if [ -n "${mfsbsd_defaultrouter}" ]; then
		echo "mfsbsd.defaultrouter=\"${mfsbsd_defaultrouter}\"" >> ${TMP_DIR}/root/boot/loader.conf
	else
		echo "mfsbsd.defaultrouter=\"\" ##################TPL#########################" >> ${TMP_DIR}/root/boot/loader.conf
	fi

	if [ -n "${mfsbsd_mac_boot}" ]; then
		echo "mfsbsd.mac_boot=\"${mfsbsd_mac_boot}\"" >> ${TMP_DIR}/root/boot/loader.conf
	else
		echo "mfsbsd.mac_boot=\"\" #######################TPL########################" >> ${TMP_DIR}/root/boot/loader.conf
	fi

	if [ -n "${mfsbsd_ip_addr}" ]; then
		echo "mfsbsd.ip_addr=\"${mfsbsd_ip_addr}\"" >> ${TMP_DIR}/root/boot/loader.conf
	else
		echo "mfsbsd.ip_addr=\"\" ########################TPL########################" >> ${TMP_DIR}/root/boot/loader.conf
	fi
	if [ -n "${mfsbsd_nameservers}" ]; then
		echo "mfsbsd.nameservers=\"${mfsbsd_nameservers}\"" >> ${TMP_DIR}/root/boot/loader.conf
	else
		echo "mfsbsd.nameservers=\"\" #######################TPL#########################" >> ${TMP_DIR}/root/boot/loader.conf
	fi
	if [ -n "${mfsbsd_autodhcp}" ]; then
		echo "mfsbsd.autodhcp=\"YES\"" >> ${TMP_DIR}/root/boot/loader.conf
	else
		echo "mfsbsd.autodhcp=\"\" ######################TPL##########################" >> ${TMP_DIR}/root/boot/loader.conf
	fi
	[ -n "${mfsbsd_ifconfig_vtnet0}" ] && echo "mfsbsd.ifconfig_vtnet0=\"${mfsbsd_ifconfig_vtnet0}\"" >> ${TMP_DIR}/root/boot/loader.conf

	if [ -n "${mfsbsd_origin_site}" ]; then
		echo "mfsbsd.origin_site=\"${mfsbsd_origin_site}\"" >> ${TMP_DIR}/root/boot/loader.conf
	else
		echo "mfsbsd.origin_site=\"\" ######################TPL##########################" >> ${TMP_DIR}/root/boot/loader.conf
	fi

	echo "#__MFS_STOP_DATA=1" >> ${TMP_DIR}/root/boot/loader.conf

	####
	echo "LOADER>>>>"
	${CAT_CMD} ${TMP_DIR}/root/boot/loader.conf
	echo "LOADER<<<<"

	return 0
}


# 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
	. ${subrdir}/jcreate.subr
	TMPFILE=$( ${MKTEMP_CMD} )

	if [ -r "${fromfile}" ]; then
		${CP_CMD} -a ${fromfile} ${TMPFILE}
		/usr/local/cbsd/misc/cbsdsysrc -qf ${TMPFILE} -x jname
		/usr/local/cbsd/misc/cbsdsysrc -qf ${TMPFILE} path="${rootpath}"
		/usr/local/cbsd/misc/cbsdsysrc -qf ${TMPFILE} data="${rootpath}"
	else

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

		[ -n "${pkglist}" ] && echo "pkglist=\"${pkglist}\";" >> ${TMPFILE}
		if [ -n "${srvlist}" -a -r "${srvlist}" ]; then
			${CAT_CMD} ${srvlist} >> ${TMPFILE}
			${RM_CMD} -f ${srvlist}
		fi
	fi

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

	${RM_CMD} -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}" ] && ${RM_CMD} -f ${JAILRCCONF}
}

# MAIN
jcleanup jname=${jname}
clear_tmp_dir

[ ${baserw} -eq 1 ] && path="${data}"

[ "${prunelist}" != "0" ] && prunelist="${sharedir}/jail2iso-prunelist"
if [ "${nobase}" != "1" ]; then
	[ ! -d "${BASE_DIR}" ] && err 1 "${N1_COLOR}No base data on: ${N2_COLOR}${BASE_DIR}${N0_COLOR}"
fi

[ -z "${dstname}" ] && dstname="${jname}-${ver}_${arch}.img"

case "${media}" in
	iso)
		make_ufs
		echo "make_ufs done"
		[ -z "${dstname}" ] && dstname="${jname}-${ver}_${arch}.iso"
		cmd="/usr/local/cbsd/release/mkisoimages.sh -l ${LABEL} -n ${dstdir}/${dstname} -d ${TMP_DIR} -e ${efi}"
		${cmd}
		_ret=$?
		if [ ${_ret} -ne 0 ]; then
			err 1 "${N1_COLOR}${CBSD_APP} error: ${N2_COLOR}${cmd}${N0_COLOR}"
		fi
		echo "mkisoimages done"
		;;
	memstick)
		make_ufs

		${MAKEFS_CMD} -B little -o version=2 -o softupdates=1 -o label=${LABEL} ${dstdir}/${dstname}.part ${TMP_DIR}
		[ $? -ne 0 ] && err 1 "${N1_COLOR}${CBSD_APP} error: ${N2_COLOR}makefs failed${N0_COLOR}"

		if [ ${efi} -eq 1 ]; then
			# efifat was deprecated in 12.2-RELEASE
			if [ -r ${TMP_DIR}/boot/boot1.efifat ]; then
				# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
				${MKIMG_CMD} -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}
			elif [ -r ${TMP_DIR}/boot/boot1.efi ]; then
				_efi_part=$( ${MKTEMP_CMD} )
				${TRUNCATE_CMD} -s64M ${_efi_part}
				unit=$( ${MDCONFIG_CMD} -a -t vnode -f ${_efi_part} 2>&1 )
				[ $? -ne 0 ] && err 1 "${N1_COLOR}${CBSD_APP}: mdconfig ${W1_COLOR}failed${N2_COLOR} ${unit}${N0_COLOR}"
				echo "stamp loader.efi: ${_efi_part}"
				tmp_mp=$( ${MKTEMP_CMD} -d )
				/sbin/newfs_msdos -F 32 -c 1 -L EFISYS /dev/${unit}
				${MOUNT_CMD} -t msdosfs /dev/${unit} ${tmp_mp}
				${MKDIR_CMD} -p ${tmp_mp}/EFI/BOOT
				case "${arch}" in
					arm64)
						${CP_CMD} /boot/loader.efi ${tmp_mp}/EFI/BOOT/bootaa64.efi
						;;
					*)
						${CP_CMD} /boot/loader.efi ${tmp_mp}/EFI/BOOT/BOOTX64.efi
						;;
				esac
				${UMOUNT_CMD} ${tmp_mp}
				${RMDIR_CMD} ${tmp_mp}
				${MDCONFIG_CMD} -d -u ${unit}
				# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
				${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${_efi_part} -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname}.part -p freebsd-swap::1M -o ${dstdir}/${dstname}
				${RM_CMD} -f ${_efi_part}
			else
				err 1 "${N1_COLOR}${CBSD_APP}: no such boot1.efi or loader.efi: ${N2_COLOR}${TMP_DIR}/boot/${N0_COLOR}"
			fi
		else
			# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
			${MKIMG_CMD} -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
		[ -r ${dstdir}/${dstname}.part ] && ${RM_CMD} -f ${dstdir}/${dstname}.part
		[ -r ${dstdir}/${dstname}-extra.part ] && ${RM_CMD} -f ${dstdir}/${dstname}-extra.part
		sync
		${DU_CMD} -sh "${dstdir}/${dstname}"
		${ECHO} "${N1_COLOR}Now you can burn image to USB memstick via\n ${N2_COLOR}dd if=${dstdir}/${dstname} of=/dev/da${W2_COLOR}X${N2_COLOR} bs=1m conv=\"sync\"${N0_COLOR}"
		;;
	mfs)
		if [ ! -x ${distdir}/modules/roothack.d/init ]; then
			${ECHO} "${N1_COLOR}MFS media requires an extra 'init' (roothack) file that is not included in the default CBSD distribution${N0_COLOR}"
			${ECHO} "${N1_COLOR}Please get this file via 'roothack' module:${N0_COLOR}"
			${ECHO} "${N2_COLOR}  cbsd module mode=install roothack${N0_COLOR}"
			${ECHO} "${N2_COLOR}  make -C /usr/local/cbsd/modules/roothack.d${N0_COLOR}"
			exit 1
		fi
		make_ufs
		echo "${TMP_DIR} done"
		OTMP_DIR="${TMP_DIR}"
		TMP_DIR="${TMP_DIR}/root"
		if [ "${mfs_struct_only}" = "1" ]; then
			${ECHO} "${N1_COLOR}${CBSD_APP} mfs_struct_only struct: ${N2_COLOR}${TMP_DIR}${N0_COLOR}"
			exit 0
		fi
		${MAKEFS_CMD} -B little -o version=2 -o softupdates=1 -o label=${LABEL} ${dstdir}/${dstname}.part ${TMP_DIR}
		[ $? -ne 0 ] && err 1 "${N1_COLOR}${CBSD_APP} error: ${N2_COLOR}makefs failed${N0_COLOR}"

		if [ -n "${extra_part}" ]; then
			[ -z "${extra_part_label}" ] && extra_part_label="cbsdextra"
			${MAKEFS_CMD} -B little -o version=2 -o softupdates=1 -o label=${extra_part_label} ${dstdir}/${dstname}-extra.part ${extra_part}
		fi

		if [ ${efi} -eq 1 ]; then
			# efifat was deprecated in 12.2-RELEASE
			if [ -r ${TMP_DIR}/boot/boot1.efifat ]; then
				# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
				${MKIMG_CMD} -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}
			elif [ -r ${TMP_DIR}/boot/boot1.efi ]; then
				_efi_part=$( ${MKTEMP_CMD} )
				${TRUNCATE_CMD} -s64M ${_efi_part}
				unit=$( ${MDCONFIG_CMD} -a -t vnode -f ${_efi_part} 2>&1 )
				[ $? -ne 0 ] && err 1 "${N1_COLOR}${CBSD_APP}: mdconfig ${W1_COLOR}failed${N2_COLOR} ${unit}${N0_COLOR}"
				echo "stamp loader.efi: ${_efi_part}"
				tmp_mp=$( ${MKTEMP_CMD} -d )
				/sbin/newfs_msdos -F 32 -c 1 -L EFISYS /dev/${unit}
				${MOUNT_CMD} -t msdosfs /dev/${unit} ${tmp_mp}
				${MKDIR_CMD} -p ${tmp_mp}/EFI/BOOT
				case "${arch}" in
					arm64)
						${CP_CMD} /boot/loader.efi ${tmp_mp}/EFI/BOOT/bootaa64.efi
						;;
					*)
						${CP_CMD} /boot/loader.efi ${tmp_mp}/EFI/BOOT/BOOTX64.efi
						;;
				esac
				${UMOUNT_CMD} ${tmp_mp}
				${RMDIR_CMD} ${tmp_mp}
				${MDCONFIG_CMD} -d -u ${unit}
				if [ "${arch}" = "arm64" ]; then
					echo "arm64 debug: bsdlabel"
					# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
					echo "${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${_efi_part} -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname}.part -p freebsd-swap::1M -o ${dstdir}/${dstname}"
					${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${_efi_part} -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname}.part -p freebsd-swap::1M -o ${dstdir}/${dstname}
				else
					# swap?
					# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
					# ${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${_efi_part} -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname}.part -p freebsd-swap::1M -o ${dstdir}/${dstname}
					if [ -r "${dstdir}/${dstname}-extra.part" ]; then
						_mk_cmd="${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${_efi_part} -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname}.part -p freebsd-ufs:=${dstdir}/${dstname}-extra.part  -p freebsd-swap::1M -o ${dstdir}/${dstname}"
					else
						_mk_cmd="${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${_efi_part} -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname}.part -p freebsd-swap::1M -o ${dstdir}/${dstname}"
					fi
					${_mk_cmd}
					_ret=$?
				fi
				${RM_CMD} -f ${_efi_part}
			else
				err 1 "${N1_COLOR}${CBSD_APP}: no such boot1.efi or loader.efi: ${N2_COLOR}${TMP_DIR}/boot/${N0_COLOR}"
			fi
		else
			# swap?
			# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
			# ${MKIMG_CMD} -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}
			if [ -r "${dstdir}/${dstname}-extra.part" ]; then
				_mk_cmd="${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p freebsd-boot:=${TMP_DIR}/boot/gptboot -p freebsd-ufs:=${dstdir}/${dstname}.part -p freebsd-ufs:=${dstdir}/${dstname}-extra.part -p freebsd-swap::1M -o ${dstdir}/${dstname}"
			else
				_mk_cmd="${MKIMG_CMD} -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
			${_mk_cmd}
			_ret=$?
		fi
		[ -r ${dstdir}/${dstname}.part ] && ${RM_CMD} -f ${dstdir}/${dstname}.part
		[ -r ${dstdir}/${dstname}-extra.part ] && ${RM_CMD} -f ${dstdir}/${dstname}-extra.part

		# ISO
		echo "/usr/local/cbsd/release/mkisoimages.sh -l ${LABEL} -n ${dstdir}/${dstname}.iso -d ${TMP_DIR} -e ${efi}"
		/usr/local/cbsd/release/mkisoimages.sh -l ${LABEL} -n ${dstdir}/${dstname}.iso -d ${TMP_DIR} -e ${efi}

		${RM_CMD} -rf ${TMP_DIR} ${OTMP_DIR}
		sync
		${DU_CMD} -sh "${dstdir}/${dstname}"
		${ECHO} "${N1_COLOR}Now you can burn image to USB memstick via\n ${N2_COLOR}dd if=${dstdir}/${dstname} of=/dev/da${W2_COLOR}X${N2_COLOR} bs=1m conv=\"sync\"${N0_COLOR}"
		;;
	bhyve|livecd)
		case "${vm_guestfs}" in
			ufs)
				make_ufs
				echo "${MAKEFS_CMD} -o optimization=space -B little -o version=2 -o softupdates -o label=${LABEL} ${dstdir}/${dstname}.part ${TMP_DIR}"
				${MAKEFS_CMD} -B little -o version=2 -o softupdates=1 -o label=${LABEL} ${dstdir}/${dstname}.part ${TMP_DIR}
				[ $? -ne 0 ] && err 1 "makefs failed"
				echo "makefs done: ${dstdir}/${dstname}.part"
				if [ -n "${swapsize}" -a "${swapsize}" != "0" ]; then
					_swap_args="-p freebsd-swap::${swapsize}"
				else
					_swap_args=
				fi

				if [ "${media}" = "livecd" ]; then
					echo "/usr/local/cbsd/release/mkisoimages.sh -l ${LABEL} -n ${dstdir}/${dstname} -d ${TMP_DIR} -e ${efi}"
					/usr/local/cbsd/release/mkisoimages.sh -l ${LABEL} -n ${dstdir}/${dstname} -d ${TMP_DIR} -e ${efi}
					[ -r ${dstdir}/${dstname}.part ] && ${RM_CMD} -f ${dstdir}/${dstname}.part
					exit 0
				fi
				if [ ${efi} -eq 1 ]; then
					# efifat was deprecated in 12.2-RELEASE
					if [ -r ${TMP_DIR}/boot/boot1.efifat ]; then
						# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
						${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${TMP_DIR}/boot/boot1.efifat -p freebsd-boot:=${TMP_DIR}/boot/gptboot ${_swap_args} -p freebsd-ufs:=${dstdir}/${dstname}.part -o ${dstdir}/${dstname}
					elif [ -r ${TMP_DIR}/boot/boot1.efi ]; then
						# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
						[ ! -r ${TMP_DIR}/boot/gptboot ] && err 1 "${N1_COLOR}${CBSD_APP}: no such boot/gptboot in hier: ${N2_COLOR}${TMP_DIR}/boot/gptboot${N0_COLOR}"
						_efi_part=$( ${MKTEMP_CMD} )
						${TRUNCATE_CMD} -s64M ${_efi_part}
						unit=$( ${MDCONFIG_CMD} -a -t vnode -f ${_efi_part} 2>&1 )
						[ $? -ne 0 ] && err 1 "${N1_COLOR}${CBSD_APP}: mdconfig ${W1_COLOR}failed${N2_COLOR} ${unit}${N0_COLOR}"
						echo "stamp loader.efi: ${_efi_part}"
						tmp_mp=$( ${MKTEMP_CMD} -d )
						/sbin/newfs_msdos -F 32 -c 1 -L EFISYS /dev/${unit}
						${MOUNT_CMD} -t msdosfs /dev/${unit} ${tmp_mp}
						${MKDIR_CMD} -p ${tmp_mp}/EFI/BOOT

						case "${arch}" in
							arm64)
								${CP_CMD} /boot/loader.efi ${tmp_mp}/EFI/BOOT/bootaa64.efi
								;;
							*)
								${CP_CMD} /boot/loader.efi ${tmp_mp}/EFI/BOOT/BOOTX64.efi
								;;
						esac

						${UMOUNT_CMD} ${tmp_mp}
						${RMDIR_CMD} ${tmp_mp}
						${MDCONFIG_CMD} -d -u ${unit}
						# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
						${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p efi:=${_efi_part} -p freebsd-boot:=${TMP_DIR}/boot/gptboot ${_swap_args} -p freebsd-ufs:=${dstdir}/${dstname}.part -o ${dstdir}/${dstname}
						${RM_CMD} ${_efi_part}
					else
						[ -r ${dstdir}/${dstname}.part ] && ${RM_CMD} -f ${dstdir}/${dstname}.part
						err 1 "${N1_COLOR}${CBSD_APP}: no such boot1.efi or loader.efi: ${N2_COLOR}${TMP_DIR}${N0_COLOR}"
					fi
				else
					# gptboot not for aarch64: jail2iso: no such boot/gptboot in hier: /usr/jails/tmp/cloud-iso.56237/boot/gptboot
					${MKIMG_CMD} -s gpt -b ${TMP_DIR}/boot/pmbr -p freebsd-boot:=${TMP_DIR}/boot/gptboot ${_swap_args} -p freebsd-ufs:=${dstdir}/${dstname}.part -o ${dstdir}/${dstname}
				fi
				if [ -n "${freesize}" ]; then
					${TRUNCATE_CMD} -s+"${freesize}" ${dstdir}/${dstname}
					unit=$( ${MDCONFIG_CMD} -a -t vnode -f ${dstdir}/${dstname} )
					echo "U: ${unit}"
					${GPART_CMD} recover ${unit}
					if [ -n "${_swap_args}" ]; then
						${GPART_CMD} resize -i4 ${unit}
						${GROWFS_CMD} -y /dev/${unit}p4
						# suj?
						#/sbin/tunefs -j enable /dev/${unit}p4
						/sbin/tunefs -n enable /dev/${unit}p4
					else
						${GPART_CMD} resize -i3 ${unit}
						${GROWFS_CMD} -y /dev/${unit}p3
						# suj?
						#/sbin/tunefs -j enable /dev/${unit}p3
						/sbin/tunefs -n enable /dev/${unit}p3
					fi
					${MDCONFIG_CMD} -d -u ${unit}
				fi
				[ -r ${dstdir}/${dstname}.part ] && ${RM_CMD} -f ${dstdir}/${dstname}.part
				[ -r ${dstdir}/${dstname}-extra.part ] && ${RM_CMD} -f ${dstdir}/${dstname}-extra.part
				;;
			zfs)
				# deprecated, rewrite:
				create_img_for_dir ${data} ${dstdir}/${dstname}
				unit=$( ${MDCONFIG_CMD} -a -t vnode -f ${dstdir}/${dstname} 2>&1 )
				[ $? -ne 0 ] && err 1 "${N1_COLOR}${CBSD_APP}: mdconfig ${W1_COLOR}failed${N2_COLOR} ${unit}${N0_COLOR}"
				bhyve_zfs_install
				;;
		esac

		mynic=$( getnics-by-ip ip=0.0.0.0 2>/dev/null skip=bridge )
		[ -z "${mynic}" ] && mynic="em0"
		[ ${quiet} -eq 0 ] && show_bhyve_message
		#${MDCONFIG_CMD} -d -u ${unit}
		;;
	*)
		err 1 "${N1_COLOR}unknown media, valid: ${N2_COLOR}iso${N1_COLOR}, ${N2_COLOR}memstick ${N1_COLOR}or ${N2_COLOR}bhyve${N0_COLOR}"
esac

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

jcleanup jname=${jname}

exit 0
