#!/usr/local/bin/cbsd
#v11.2.1
MYARG="mode"
MYOPTARG="name path display type jname"
MYDESC="Operate with virtual storage media such as ISO"
CBSDMODULE="sys"
EXTHELP="wf_bhyve"
ADDHELP="mode=attach - attach media to jname\n\
mode=detach - detach media from jname\n\
mode=list - list of registered media\n\
mode=flushall - unregister all records, without deleting\n\
mode=register - register new media (req: name, path)\n\
mode=unregister - unregister new media (req: name, path), without delete\n\
mode=delete|remove - unregister and delete media file (req: name, path)\n\
mode=deleteall|removeall - unregister and delete all ISO files\n\
mode=get - print 'name' or 'path' for 'path=' or 'name='\n\
mode=update - update type or jname by 'path=' and 'name='\n\
mode=dump - dump SQL records by line\n\
mode=eject - eject CD/ISO from VM\n\
type=iso,hdd or shared\n\
sectorsize= custom sectorsize for register mode\n\
display= list by comma for column. Default: name,path,type,jname,size\n"

. ${subrdir}/nc.subr

. ${cbsdinit}

. ${system}
. ${subrdir}/bhyve.subr
. ${subrdir}/xen.subr
. ${subrdir}/virtual.subr

if [ "${mod_cbsd_queue_enabled}" = "YES" -a -z "${MOD_CBSD_QUEUE_DISABLED}" ]; then
	readconf cbsd_queue.conf
	[ -z "${cbsd_queue_backend}" ] && MOD_CBSD_QUEUE_DISABLED="1"
fi

[ -z "${display}" ] && display="name,path,type,jname,size"

#remove commas for loop action on header
mydisplay=$( echo ${display} | ${TR_CMD} ',' ' ' )

# upper for header
myheader=$( echo ${mydisplay} | ${TR_CMD} '[:lower:]' '[:upper:]' )

show_header()
{
	local _header="${H1_COLOR}${BOLD}${myheader}${N0_COLOR}"
	[ ${header} -eq 1 ] && ${ECHO} "${_header}"
}

# dummy function when no $emulator
dummy_remove_dsk()
{

}

# construct and print full path or $1 is relative
normalize_full_path()
{
	local _path_pref _tmp_path

	# is full path?
	_path_pref=$( substr --pos=0 --len=1 --str=${1} )

	if [ "${_path_pref}" = "/" ]; then
		_tmp_path="${1}"
	else
		if [ -z "${jname}" ]; then
			err 1 "media: normalize_full_path: jname is empty for init ${1} full path"
		fi
			_tmp_path="${jaildatadir}/${jname}-data/${1}"
	fi

	printf "${_tmp_path}"
}


# 1) if -n name -p path -t type exist for jail='-' than UPDATE this records to -j jname
# 2) if -n name -p path -t type not exist for jail='-', remove records for -j jname
unregister_or_remove()
{
	local rec_num
	local exist
	local name path type jname

	while getopts "n:p:t:j:" opt; do
		case "${opt}" in
			n) name="${OPTARG}" ;;
			p) path="${OPTARG}" ;;
			t) type="${OPTARG}" ;;
			j) jname="${OPTARG}" ;;
		esac
		shift $(($OPTIND - 1))
	done

	path=$( normalize_full_path ${path} )

	if [ -z "${jname}" -o "${jname}" = "-" ]; then
		cbsdsqlrw storage_media "DELETE FROM media WHERE jname=\"${jname}\" AND name=\"${name}\" AND path=\"${path}\" AND type=\"${type}\""
		return 0
	fi

	rec_num=$( cbsdsqlro storage_media SELECT COUNT\(path\) FROM media WHERE name=\"${name}\" AND path=\"${path}\" AND type=\"${type}\" AND jname != \"${jname}\" )

	if [ "${rec_num}" = "0" ]; then
		# this is last one, clean ISO register and drop to unassigned stage
		cbsdsqlrw storage_media "UPDATE media SET jname='-' WHERE jname=\"${jname}\" AND type=\"${type}\" AND name=\"${name}\" AND path=\"${path}\""

	else
		# delete iso registered when we have greater then 1 records with path= name=
		cbsdsqlrw storage_media "DELETE FROM media WHERE jname=\"${jname}\" AND name=\"${name}\" AND path=\"${path}\" AND type=\"${type}\""
	fi

	# delete from domain local db
	cbsdsqlrw ${jailsysdir}/${jname}/local.sqlite "DELETE FROM ${emulator}dsk WHERE dsk_path=\"hdd-${name}\" AND dsk_type=\"${type}\""

	# CBSD QUEUE
	if [ "${mod_cbsd_queue_enabled}" = "YES" -a -z "${MOD_CBSD_QUEUE_DISABLED}" ]; then
		[ -n "${cbsd_media_queue_name}" ] && ${cbsd_queue_backend} cbsd_queue_name=${cbsd_media_queue_name} cmd=refresh
	fi
	return 0
}

# 1) if -n name -p path -t type exist for jail='-' than UPDATE this records to -j jname
# 2) if -n name -p path -t type not exist for jail='-', add records for -j jname
register_or_add()
{
	local rec_num
	local exist
	local name path type jname
	local size
	local dsk_sectorsize=

	while getopts "n:p:t:j:z:" opt; do
		case "${opt}" in
			n) name="${OPTARG}" ;;
			p) path="${OPTARG}" ;;
			t) type="${OPTARG}" ;;
			j) jname="${OPTARG}" ;;
			z) dsk_sectorsize="${OPTARG}" ;;
		esac
		shift $(($OPTIND - 1))
	done

	path=$( normalize_full_path ${path} )

	populate_dsk_size ${path}
	size=${dsk_bsize}
	[ -z "${size}" ] && size=0

	if [ -z "${jname}" -o "${jname}" = "-" ]; then
		rec_num=$( cbsdsqlro storage_media SELECT COUNT\(path\) FROM media WHERE name=\"${name}\" AND path=\"${path}\" AND type=\"${type}\" AND jname=\"-\" )
		[ "${rec_num}" != "0" ] && return 0
		cbsdsqlrw storage_media "INSERT INTO media ( name, path, type, jname, size ) VALUES ( \"${name}\", \"${path}\", \"${type}\", \"${jname}\", \"${size}\" )"
		return 0
	fi

	rec_num=$( cbsdsqlro storage_media SELECT COUNT\(path\) FROM media WHERE name=\"${name}\" AND path=\"${path}\" AND type=\"${type}\" AND jname=\"-\" )

	if [ "${rec_num}" = "1" ]; then
		cbsdsqlrw storage_media "UPDATE media SET jname=\"${jname}\" WHERE jname=\"-\" AND name=\"${name}\" AND path=\"${path}\" AND type=\"${type}\""
	else
		cbsdsqlrw storage_media "INSERT INTO media ( name, path, type, jname, size ) VALUES ( \"${name}\", \"${path}\", \"${type}\", \"${jname}\", \"${size}\" )"
	fi

	# add to domain local db
	cbsdsqlrw ${jailsysdir}/${jname}/local.sqlite "DELETE FROM ${emulator}dsk WHERE dsk_path=\"hdd-${name}\" AND dsk_type=\"${type}\""

	# CBSD QUEUE
	if [ "${mod_cbsd_queue_enabled}" = "YES" -a -z "${MOD_CBSD_QUEUE_DISABLED}" ]; then
		[ -n "${cbsd_media_queue_name}" ] && ${cbsd_queue_backend} cbsd_queue_name=${cbsd_media_queue_name} cmd=refresh
	fi

	return 0
}

# if $1 = "Unregister" then overwrite status to "Unregister"
populate_output_data()
{
	local _i _val

	_status=

	#populate values for in output string
	for _i in ${mydisplay}; do
		case "${_i}" in
			size)
				_val=
				eval _val=\$$_i

				if conv2human "${_val}"; then
					_val=${convval}
				fi
				;;
			*)
				_val=
				eval _val=\$$_i
				[ -z "${_val}" ] && _val="\-"
				prefix=$( substr --pos=0 --len=1 --str=${_val} )
				[ "${prefix}" = "-" ] && _val="\-"
				;;
		esac
		if [ -z "${_status}" ]; then
			_status="${N0_COLOR}${_val}"
		else
			_status="${_status} ${_val}"
		fi
	done
}


# $1 - which file from. Eg: local
show_data_from_sql()
{
	local _i

	_sql="SELECT name,path,type,jname,size FROM media"

	cbsdsqlro storage_media ${_sql} | while read name path type jname size; do
		populate_output_data
		printf "${N2_COLOR}"
		printf "${_status}"
		printf "${N0_COLOR}\n"
	done

	IFS=" "
}


show_local()
{
	local _errcode _status

	show_header
	show_data_from_sql local
}

show_vhid()
{
	show_local
}


# select into $vm_res variable path of media by name
# return 0 if data exist
# $1 - alternative jname
select_by_name()
{
	local j="${jname}"

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

	vm_res=$( cbsdsqlro storage_media SELECT path FROM media WHERE name=\"${name}\" AND jname=\"${j}\" )

	[ -z "${vm_res}" ] && return 1

	return 0
}

# select into $vm_res variable name of media by path
# return 0 if data exist
# $1 - alternative jname
select_by_path()
{
	local j="${jname}"

	[ -n "${1}" ] && j="${1}"
	vm_res=$( cbsdsqlro storage_media SELECT name FROM media WHERE path=\"${path}\" AND jname=\"${j}\" )

	[ -z "${vm_res}" ] && return 1

	return 0
}

update_jname()
{
	cbsdsqlrw storage_media "UPDATE media SET jname=\"${jname}\" WHERE name=\"${name}\" AND path=\"${path}\""
}

update_type()
{
	cbsdsqlrw storage_media "UPDATE media SET type=\"${type}\" WHERE name=\"${name}\" AND path=\"${path}\" AND jname=\"${jname}\""
}

check_protected()
{
	local _emulator
	local _table

	[ "${jname}" = "-" ] && return 0

	_emulator=$( cbsdsqlro local SELECT emulator FROM jails WHERE jname=\"${jname}\" )

	case "${_emulator}" in
		jail)
			_table="jails"
			;;
		bhyve)
			_table="bhyve"
			;;
		xen)
			_table="xen"
			;;
	esac

	protected=$( cbsdsqlro local SELECT protected FROM ${_table} WHERE jname=\"${jname}\" )

	[ -z "${protected}" ] && protected="0"	# by default - is not protected
	[ "${protected}" = "1" ] && err 1 "${N1_COLOR}Environment is protected to delete: ${N2_COLOR}${jname}${N0_COLOR}"
}


storage_attach()
{
	local _data_dir_path _tmp_dir_path= _tmp_dsk_path= _res

	[ -z "${name}" ] && err 1 "${N1_COLOR}media: ${N2_COLOR}name=${N0_COLOR}"
	[ -z "${path}" ] && err 1 "${N1_COLOR}media: ${N2_COLOR}path=${N0_COLOR}"
	[ -z "${jname}" ] && err 1 "${N1_COLOR}Give me ${N2_COLOR}jname=${N0_COLOR}"

	local attached_to_name dsk_path dsk_name
	local mydb virtio_type already_attached_to_me

	attached_to_jname=$( cbsdsqlro storage_media SELECT jname FROM media WHERE path=\"${path}\" AND name=\"${name}\" AND jname!=\"${jname}\" LIMIT 1 )

	# not attached?
	if [ "${attached_to_jname}" = "-" ]; then
		by_path="-"
		by_name="-"
		attached_to_jname=
	else
		by_path="${path}"
		by_name="${name}"
	fi

	# todo: shared disk
	if [ "${type}" = "hdd" ]; then
		[ -n "${attached_to_jname}" ] && err 1 "${N1_COLOR}disk ${name} with path ${path} already attached to: ${N2_COLOR}${test_jname}${N0_COLOR}"
		select_by_path "${by_path}"
		[ $? -ne 0 ] && err 1 "${N1_COLOR}Path not exist for jname by path ${by_path}: ${N2_COLOR}${path}${N0_COLOR}"
		select_by_name "${by_name}"
		[ $? -ne 0 ] && err 1 "${N1_COLOR}Name not exist for jname by name ${by_name}: ${N2_COLOR}${name}${N0_COLOR}"
	fi

	# save variables before rcconf init
	dsk_path="${path}"
	dsk_name="${name}"

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

	if [ -z "${type}" ]; then
		type=$( imgtype path=${dsk_path} 2>&1 )
		${ECHO} "${N1_COLOR}media: auto-detected image type for ${dsk_path}: ${N2_COLOR}${type}${N0_COLOR}"
	fi

	case "${type}" in
		iso|shared)
			;;
		hdd)
			mydb="${jailsysdir}/${jname}/local.sqlite"
			virtio_type="virtio-blk"
			# simplify if the file is located in the data directory
			_data_dir_path="${jaildatadir}/${jname}-data"
			_tmp_dir_path=$( /usr/bin/dirname ${dsk_path} )
			if [ "${_data_dir_path}" = "${_tmp_dir_path}" ]; then
				_tmp_dsk_path=$( /usr/bin/basename ${dsk_path} )
			else
				_tmp_dsk_path="${dsk_path}"
			fi
			_res=$( cbsdsqlro ${mydb} SELECT dsk_path FROM bhyvedsk WHERE jname=\"${jname}\" AND dsk_path=\"${_tmp_dsk_path}\" LIMIT 1 2>/dev/null )
			if [ -n "${_res}" ]; then
				${ECHO} "${N1_COLOR}dsk_path already exist for ${jname}: ${N2_COLOR}${_tmp_dsk_path}${N0_COLOR}"
				return 1
			fi
			cbsdsqlrw ${mydb} "INSERT INTO ${emulator}dsk ( jname,dsk_controller,dsk_path,dsk_slot ) VALUES ( \"${jname}\",\"${virtio_type}\",\"${_tmp_dsk_path}\","0" )"
			;;
	esac

	# test for already attached
	already_attached_to_me=$( cbsdsqlro storage_media SELECT jname FROM media WHERE path=\"${dsk_path}\" AND name=\"${dsk_name}\" AND jname=\"${jname}\" LIMIT 1 )

	[ -n "${already_attached_to_me}" ] && err 1 "${N1_COLOR}storage with name:${name} and path:${path} already attached for instance: ${N2_COLOR}${jname}${N0_COLOR}"

	if [ -n "${attached_to_jname}" ]; then
		#shared disk: INSERT
		sql="INSERT INTO media ( name, path, type, jname ) VALUES ( \"${dsk_name}\", \"${dsk_path}\", \"${type}\", \"${jname}\" )"
	else
		sql="UPDATE media SET jname=\"${jname}\" WHERE name=\"${dsk_name}\" AND path=\"${dsk_path}\""
	fi

	echo "${sql}"
	cbsdsqlrw ${dbdir}/storage_media.sqlite "${sql}"

	# CBSD QUEUE
	if [ "${mod_cbsd_queue_enabled}" = "YES" -a -z "${MOD_CBSD_QUEUE_DISABLED}" ]; then
		[ -n "${cbsd_media_queue_name}" ] && ${cbsd_queue_backend} cbsd_queue_name=${cbsd_media_queue_name} cmd=refresh
	fi

	return 0
}


storage_detach()
{
	[ -z "${name}" ] && err 1 "${N1_COLOR}media: ${N2_COLOR}name=${N0_COLOR}"
	[ -z "${path}" ] && err 1 "${N1_COLOR}media: ${N2_COLOR}path=${N0_COLOR}"
	[ -z "${jname}" ] && err 1 "${N1_COLOR}Give me ${N2_COLOR}jname=${N0_COLOR}"

	local dsk_path dsk_name
	local mydb virtio_type already_attached_to_me

	attached_to_me=$( cbsdsqlro storage_media SELECT jname FROM media WHERE path=\"${path}\" AND name=\"${name}\" AND jname=\"${jname}\" LIMIT 1 )
	[ "${attached_to_me}" != "${jname}" ] && err 1 "${N1_COLOR}disk ${name} with name:${name} and path:${path} is not attached to: ${N2_COLOR}${jname}${N0_COLOR}"

	attached_to_jname=$( cbsdsqlro storage_media SELECT jname FROM media WHERE path=\"${path}\" AND name=\"${name}\" AND jname!=\"${jname}\" LIMIT 1 )

	# not attached?
	if [ "${attached_to_jname}" = "-" ]; then
		by_path="-"
		by_name="-"
		attached_to_jname=
	else
		by_path="${path}"
		by_name="${name}"
	fi

	# save variables before rcconf init
	dsk_path="${path}"
	dsk_name="${name}"

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

	case "${type}" in
		iso|shared)
			;;
		hdd)
			mydb="${jailsysdir}/${jname}/local.sqlite"
			cbsdsqlrw ${mydb} "DELETE FROM ${emulator}dsk WHERE dsk_path=\"${dsk_path}\" AND name=\"${dsk_name}\""
			;;
	esac

	if [ -n "${attached_to_jname}" ]; then
		# shared disk: delete record with my jname
		sql="DELETE FROM media WHERE name=\"${dsk_name}\" AND path=\"${dsk_path}\" AND jname=\"${jname}\""
	else
		# disk is orphaned now: drop to '-' jname
		sql="UPDATE media SET jname='-' WHERE jname=\"${jname}\" AND name=\"${dsk_name}\" AND path=\"${dsk_path}\""
	fi

	echo "${sql}"
	cbsdsqlrw ${dbdir}/storage_media.sqlite "${sql}"

	# CBSD QUEUE
	if [ "${mod_cbsd_queue_enabled}" = "YES" -a -z "${MOD_CBSD_QUEUE_DISABLED}" ]; then
		[ -n "${cbsd_media_queue_name}" ] && ${cbsd_queue_backend} cbsd_queue_name=${cbsd_media_queue_name} cmd=refresh
	fi

	case "${type}" in
		hdd)
			mydb="${jailsysdir}/${jname}/local.sqlite"
			cbsdsqlrw ${mydb} "DELETE FROM ${emulator}dsk WHERE dsk_path=\"${dsk_path}\""
			;;
		iso)
			bset mode=quiet jname=${jname} vm_iso_path=''
			;;
	esac

	return 0
}


eject()
{
	cbsdsqlrw storage_media "UPDATE media SET jname='-' WHERE jname=\"${jname}\" AND type=\"iso\""
}

which_vm_depens_on_zvol()
{
	local _vm_list _vol="${1}"

	[ -z "${_vol}" ] && return 0

	_vm_list=$( /sbin/zfs list -H -r -t snapshot -o name ${_vol} | ${CUT_CMD} -d '@' -f 2 | ${CUT_CMD} -d '-' -f 2 | ${XARGS_CMD} )

	[ -z "${_vm_list}" ] && return 0
	printf "${_vm_list}"
	return 1
}


# try to remove ISO file
try_to_rm()
{
	local path="${1}"
	local _vm_list

	[ -z "${path}" ] && err 1 "${N1_COLOR}media: try_to_rm: empty path${N0_COLOR}"

	. ${subrdir}/zfs.subr
	if is_getzvol ${path}; then
		/sbin/zfs list ${is_zvol} > /dev/null 2>&1
		if [ $? -eq 0 ]; then

			_vm_list=$( which_vm_depens_on_zvol ${is_zvol} )

			[ -n "${_vm_list}" ] && err 1 "${N1_COLOR}Current vm depends from ${is_zvol}: ${N2_COLOR}${_vm_list}${N0_COLOR}"

			# zvol exist
			/sbin/zfs destroy ${is_zvol}
			_ret=$?
			[ ${_ret} -ne 0 ] && err 1 "${N1_COLOR}Unable to destroy zvol, please remove it by hand: ${N2_COLOR}${is_zvol}${N0_COLOR}"
		fi
	fi
	/bin/rm -f ${path}
	return 0
}


#### MAIN
[ -z "${header}" ] && header=1
sqldelimer=" "
vm_res=

if [ -n "${jname}" ]; then
	emulator=$( cbsdsqlro local SELECT emulator FROM jails WHERE jname=\"${jname}\" )
else
	emulator="dummy"
fi

case "${mode}" in
	attach)
		storage_attach
		err 0 "${N1_COLOR}Attached to: ${N2_COLOR}${jname}${N0_COLOR}"
		;;
	detach)
		storage_detach
		err 0 "${N1_COLOR}Detach to: ${N2_COLOR}${jname}${N0_COLOR}"
		;;
	eject)
		[ -z "${jname}" ] && err 1 "${N1_COLOR}Please specify ${N2_COLOR}jname=${N0_COLOR}"
		eject
		err 0 "${N1_COLOR}All CD/ISO ejected: ${N2_COLOR}${jname}${N0_COLOR}"
		;;
	list)
		show_local | /usr/bin/column -t
		;;
	get)
		[ -z "${name}" -a -z "${path}" ] && err 1 "${N1_COLOR}media: ${N2_COLOR}name=${N1_COLOR} or ${N2_COLOR}path=${N1_COLOR} value is reguired${N0_COLOR}"
		[ -n "${name}" -a -n "${path}" ] && err 1 "${N1_COLOR}media: Please specify ${N2_COLOR}name=${N1_COLOR} OR ${N2_COLOR}path=${N1_COLOR}, not both${N0_COLOR}"
		[ -n "${name}" ] && select_by_name
		[ -n "${path}" ] && select_by_path
		err 0 "${vm_res}"
		;;
	register)
		[ -z "${name}" ] && err 1 "${N1_COLOR}media: ${N2_COLOR}name=${N1_COLOR} is mandatory${N0_COLOR}"
		[ -z "${path}" ] && err 1 "${N1_COLOR}media: ${N2_COLOR}path=${N1_COLOR} is mandatory${N0_COLOR}"
		select_by_path && err 1 "${N1_COLOR}Path already exist for: ${N2_COLOR}${vm_res}${N0_COLOR}"
		select_by_name && err 1 "${N1_COLOR}Name already exist for: ${N2_COLOR}${vm_res}${N0_COLOR}"

		if [ -z "${type}" ]; then
			type=$( imgtype path=${path} 2>&1 )
			${ECHO} "${N1_COLOR}media: auto-detected image type for ${path}: ${N2_COLOR}${type}${N0_COLOR}"
		fi

		[ -z "${jname}" ] && jname="-"

		register_or_add -n "${name}" -p "${path}" -t "${type}" -j "${jname}"

		# CBSD QUEUE
		if [ "${mod_cbsd_queue_enabled}" = "YES" -a -z "${MOD_CBSD_QUEUE_DISABLED}" ]; then
			[ -n "${cbsd_media_queue_name}" ] && ${cbsd_queue_backend} cbsd_queue_name=${cbsd_media_queue_name} cmd=refresh
		fi

		${ECHO} "${N1_COLOR}Updated${N0_COLOR}" 1>&2
		exit 0
		;;
	unregister)
		[ -z "${type}" ] && type="hdd"
		[ -z "${jname}" ] && jname="-"

		check_protected

		[ -z "${name}" -a -z "${path}" ] && err 1 "${N1_COLOR}media: ${N2_COLOR}name=${N1_COLOR} or ${N2_COLOR}path=${N1_COLOR} value is reguired${N0_COLOR}"

		if [ -n "${name}" -a -n "${path}" ]; then
			unregister_or_remove -n "${name}" -p "${path}" -t "${type}" -j "${jname}"
		elif [ -n "${name}" ]; then
			cbsdsqlrw storage_media "DELETE FROM media WHERE name=\"${name}\" AND jname=\"${jname}\""
		elif [ -n "${path}" ]; then
			cbsdsqlrw storage_media "DELETE FROM media WHERE path=\"${path}\" AND jname=\"${jname}\""
		fi

		# CBSD QUEUE
		if [ "${mod_cbsd_queue_enabled}" = "YES" -a -z "${MOD_CBSD_QUEUE_DISABLED}" ]; then
			[ -n "${cbsd_media_queue_name}" ] && ${cbsd_queue_backend} cbsd_queue_name=${cbsd_media_queue_name} cmd=refresh
		fi

		err 0 "${N1_COLOR}Unregistered${N0_COLOR}"
		;;
	flushall)
		# test for protected by select jname ???
		cbsdsqlrw storage_media "DELETE FROM media WHERE type != \"hdd\""

		# CBSD QUEUE
		if [ "${mod_cbsd_queue_enabled}" = "YES" -a -z "${MOD_CBSD_QUEUE_DISABLED}" ]; then
			[ -n "${cbsd_media_queue_name}" ] && ${cbsd_queue_backend} cbsd_queue_name=${cbsd_media_queue_name} cmd=refresh
		fi

		err 0 "${N1_COLOR}Flushed${N0_COLOR}"
		;;
	delete|remove)
		[ -z "${type}" ] && err 1 "${N2_COLOR}type= ${N1_COLOR}is mandatory${N0_COLOR}"
		[ -z "${jname}" ] && jname="-"

		check_protected

		[ -z "${name}" -a -z "${path}" ] && err 1 "${N1_COLOR}media: ${N2_COLOR}name=${N1_COLOR} or ${N2_COLOR}path=${N1_COLOR} value is reguired${N0_COLOR}"

		if [ -n "${name}" -a -n "${path}" ]; then

			# need before actual delete from SQL due to zvol deps check
			[ "${type}" = "iso" ] && try_to_rm ${path}

			if [ "${jname}" = "-" ]; then
				cbsdsqlrw storage_media "DELETE FROM media WHERE name=\"${name}\" AND path=\"${path}\" AND type=\"${type}\""
			else
				cbsdsqlrw storage_media "DELETE FROM media WHERE name=\"${name}\" AND path=\"${path}\" AND type=\"${type}\" AND jname=\"${jname}\""
			fi

		else
			if [ -n "${name}" ]; then
				select_by_name
				path="${vm_res}"
				cbsdsqlrw storage_media "DELETE FROM media WHERE name=\"${name}\" AND jname=\"${jname}\""
			elif [ -n "${path}" ]; then
				# need before actual delete from SQL due to zvol deps check
				[ "${type}" = "iso" ] && try_to_rm ${path}
				cbsdsqlrw storage_media "DELETE FROM media WHERE path=\"${path}\" AND jname=\"${jname}\""
			fi
		fi

		[ -z "${path}" ] && err 1 "${N1_COLOR}media delete: empty path variable${N0_COLOR}"

		short_dsk_path=$( /usr/bin/basename ${path} )

		case "${type}" in
			iso)
				try_to_rm -f ${path}
				;;
			vhd|hdd)
				if [ "${jname}" != "-" ]; then
					mydb="${jailsysdir}/${jname}/local.sqlite"
					cbsdsqlrw ${mydb} "DELETE FROM ${emulator}dsk WHERE dsk_path=\"${short_dsk_path}\""
				fi
				${emulator}_remove_dsk ${short_dsk_path}
				;;
		esac

		# CBSD QUEUE
		if [ "${mod_cbsd_queue_enabled}" = "YES" -a -z "${MOD_CBSD_QUEUE_DISABLED}" ]; then
			[ -n "${cbsd_media_queue_name}" ] && ${cbsd_queue_backend} cbsd_queue_name=${cbsd_media_queue_name} cmd=refresh
		fi

		err 0 "${N1_COLOR}Deleted${N0_COLOR}"
		;;
	deleteall|removeall)
		for i in $( cbsdsqlro storage_media SELECT path FROM media WHERE type != \"hdd\" ); do
			${ECHO} "${N1_COLOR}removing: ${N2_COLOR}${i}${N1_COLOR} ...${N0_COLOR}"
			media mode=remove path="${i}" type="iso"
		done
		exit 0
		;;
	update)
		[ -n "${type}" ] && update_type
		[ -n "${jname}" ] && update_jname
		;;
	dump)
		# export media data to ascii file
		[ ! -r ${dbdir}/storage_media.sqlite ] && err 1 "${N1_COLOR}Not readable: ${N2_COLOR}${dbdir}/storage_media.sqlite${N0_COLOR}"
		if [ -n "${jname}" ]; then
			_sql="SELECT name,path,type,size,jname FROM media WHERE jname=\"${jname}\""
		else
			_sql="SELECT name,path,type,size,jname FROM media"
		fi
		osqldelimer=${sqldelimer}
		sqldelimer="|"
		OIFS=${IFS}
		IFS="|"
		cbsdsqlrw storage_media ${_sql} | while read name path type size jname; do
			_mysql="INSERT INTO media ( name, path, type, size, jname ) VALUES ( \"${name}\", \"${path}\", \"${type}\", \"${size}\", \"${jname}\" );"
			echo "${_mysql}"
		done
		IFS=${OIFS}
		sqldelimer=${osqldelimer}
		;;
	*)

		err 1 "${N1_COLOR}Unknown mode: ${N2_COLOR}${mode}${N0_COLOR}"
		;;
esac

exit 0
