#!/usr/local/bin/cbsd
#v11.1.6
globalconf="${distdir}/cbsd.conf";
CBSDMODULE="jail"
MYARG="jname"
MYOPTARG="sharedfs"
MYDESC="Force unmount and cleanup for offline jail"
MYDESC="Force to cleanup/unmount jail related stuff, e.g. epair, fstabs"
ADDHELP="
${H3_COLOR}Description${N0_COLOR}:

 After launching and stopping (crash) of the jails in the host system, some jail-specific
settings may remain in runtime, which are no longer needed. This script finds these settings and
deletes. For example, destroys pseudo network of jail, unmount mount point in jails, remove
traffic counter and so on...

${H3_COLOR}Options${N0_COLOR}:

 ${N2_COLOR}jname=${N0_COLOR}    - target VM;
 ${N2_COLOR}sharedfs=${N0_COLOR} - set to '1' for check DFS lockfile, when jails on DFS (cluster/shared filesystem);

${H3_COLOR}Examples${N0_COLOR}:

 # cbsd jcleanup jname=myvm1

"

# Cleanup all items of broken jail
. ${subrdir}/nc.subr
. ${system}
. ${mdtools}
. ${strings}

sharedfs=0

. ${cbsdinit}

. ${subrdir}/rcconf.subr
[ $? -eq 1 ] && return 0 #only for registered jails

# remove zombie jail
if [ "${jid}" != "0" ]; then
	if [ "${platform}" != "DragonFly" ]; then
		${JAIL_CMD} -r ${jid}
	fi
	 ${miscdir}/sqlcli ${dbdir}/local.sqlite "UPDATE jails SET jid=\"0\" WHERE jname=\"${jname}\""
fi

[ "${mdsize}" != "0" ] && MDFILE=$( eval find_md_by_mountpath ${data} )
[ ${baserw} -eq 1 ] && path="${data}"

rootflags=

if [ ${baserw} -eq 1 ]; then
	#test for zfs mounted in baserw=1
	case ${zfsfeat} in
		1)
			[ -z "${zfs_always_unload_key}" ] && zfs_always_unload_key="0"
			. ${subrdir}/zfs.subr
			zfsmnt ${data}
			if [ $? -eq 1 ]; then
				# dont remove ~cbsd/jails-data/$jname-data
				[ "${zfs_always_unload_key}" = "0" ] && rootflags="no_unmount_root"
			fi
		;;
	esac
fi

# cleanup ipfw counter
fwcounters jname=${jname} mode=remove

if [ ${baserw} -eq 1 ]; then
	umount_cdirs ${data} ${rootflags}
else
	umount_cdirs ${path} ${rootflags}
fi

[ "${mdsize}" != "0" -a -n "${MDFILE}" ] && unmountmd md=${MDFILE}

case ${zfsfeat} in
	1)
		readconf zfs.conf		# lookup for zfs_always_unload_key
		[ -z "${zfs_always_unload_key}" ] && zfs_always_unload_key="0"
		if [ "${zfs_always_unload_key}" = "1" ]; then
			. ${subrdir}/zfs.subr
			zfsmnt ${data} > /dev/null 2>&1
			ret=$?
			if [ ${ret} -ne 0 ]; then
				# is ZFS
				encryption=$( ${ZFS_CMD} get -Ho value encryption ${data} 2>/dev/null | ${AWK_CMD} '{printf $1 }' )
				[ -z "${encryption}" ] && encryption="off"
				case "${encryption}" in
					off)
						continue
						;;
					*)
						cbsdlogger NOTICE ${CBSD_APP}: unload-key for jail ${jname} enabled via zfs_always_unload_key, pool: ${ZPOOL}
						${ZFS_CMD} unmount ${data}
						_res=$( ${ZFS_CMD} unload-key ${ZPOOL} 2>&1 )
						ret=$?
						if [ ${ret} -ne 0 ]; then
							${ECHO} "${W1_COLOR}${CBSD_APP} warning: ${N1_COLOR}unload-key error for jail ${jname}, pool: ${ZPOOL}: ${N2_COLOR}${_res}${N0_COLOR}"
							cbsdlogger WARNING ${CBSD_APP}: unload-key error for jail ${jname}, pool: ${ZPOOL}: ${_res}
						else
							${ECHO} "${N1_COLOR}${CBSD_APP}: zfs encription unload-key for: ${N2_COLOR}${ZPOOL}${N0_COLOR}"
						fi
						;;
				esac
			fi
		fi
		;;
esac

jaillock="${jailsysdir}/${jname}/locked"
if [ ${sharedfs} -eq 0 ]; then
	[ -f "${jaillock}" ] && ${RM_CMD} -f ${jaillock}
fi

# vnet cleanup
if [ "${vnet}" = "1" ]; then

	epair_if=$( ${IFCONFIG_CMD} -g epair )

	for i in ${epair_if}; do
		mydesc=$( ${IFCONFIG_CMD} ${i}  2>/dev/null | ${AWK_CMD} '/description:/{print $2}' )
		[ -z "${mydesc}" ] && continue
		desc_part="${jname}-eth"
		len=$( strlen "${desc_part}" )
		find_part=$( substr --pos=0 --len=${len} --str="${mydesc}" )
		if [ "${desc_part}" = "${find_part}" ]; then
			${ECHO} "${N1_COLOR}jcleanup: destroy epair for ${jname}: ${N2_COLOR}${i}${N0_COLOR}"
			${IFCONFIG_CMD} ${i} destroy
		fi
	done
fi

exit 0
