xref: /freebsd/libexec/rc/rc.d/cfumass (revision 19fae0f66023a97a9b464b3beeeabb2081f575b3)
1#!/bin/sh
2#
3# $FreeBSD$
4#
5
6# PROVIDE: cfumass
7# REQUIRE: var
8# KEYWORD: nojail
9
10. /etc/rc.subr
11
12name="cfumass"
13desc="Configure the LUN for device mode USB mass storage"
14rcvar="cfumass_enable"
15
16start_cmd="${name}_start"
17stop_cmd="${name}_stop"
18
19extra_commands="reload"
20reload_cmd="${name}_start"
21
22: ${cfumass_dir:=/var/cfumass}
23: ${cfumass_image:=/var/tmp/cfumass.img}
24: ${cfumass_vendor:="FreeBSD"}
25: ${cfumass_product:="cfumass(4)"}
26
27remove_luns()
28{
29	local _lun _luns
30
31	_luns=`ctladm devlist -b block -v | awk '
32
33	$1 ~ /^[0-9]+$/ {
34		lun = $1
35	}
36
37	$1 == "file='"${cfumass_image}"'" {
38		print lun
39	}'`
40
41	for _lun in ${_luns}; do
42		ctladm remove -b block -l "${_lun}" > /dev/null
43	done
44}
45
46cfumass_start()
47{
48	local err _files _template _new_template
49
50	if [ ! -d "${cfumass_dir}" ]; then
51		warn "${cfumass_dir} does not exist"
52		return 1
53	fi
54
55	_files=`find "${cfumass_dir}" -newer "${cfumass_image}" -print 2> /dev/null`
56	if [ ! -e "${cfumass_image}" -o -n "${_files}" ]; then
57		# The image doesn't exist or is out of date.
58		makefs -t cd9660 -o label="${cfumass_vendor}" \
59		    -o rockridge "${cfumass_image}" "${cfumass_dir}"
60		err=$?
61		if [ "${err}" -ne 0 ]; then
62			warn "unable to create ${cfumass_image}"
63			return "${err}"
64		fi
65	fi
66
67	remove_luns
68
69	ctladm create -b block -o file="${cfumass_image}" -o readonly=on \
70	    -o vendor="${cfumass_vendor}" -o product="${cfumass_product}" \
71	    -S 0 > /dev/null
72	err=$?
73	if [ "${err}" -ne 0 ]; then
74		warn "unable to create CTL LUN"
75		return "${err}"
76	fi
77
78	load_kld -e cfumass cfumass
79
80	# If the template is already switched to Mass Storage, then reset
81	# it to -1 to force the host to reenumerate it; otherwise it might
82	# not notice the new LUN.
83	_template=`sysctl -n hw.usb.template`
84	if [ "${_template}" -eq 0 ]; then
85		sysctl hw.usb.template=-1 > /dev/null
86		err=$?
87		if [ "${err}" -ne 0 ]; then
88			warn "unable to set hw.usb.template sysctl"
89			return "${err}"
90		fi
91	fi
92
93	# Set the template number based on the current one.
94	_template=`sysctl -n hw.usb.template`
95	case "${_template}" in
96	-1)
97		_new_template="0"
98		;;
99	8)
100		_new_template="10"
101		;;
102	*)
103		warn "hw.usb.template sysctl set to neither -1 nor 8; not changing"
104		_new_template=""
105		;;
106	esac
107
108	if [ -n "${_new_template}" ]; then
109		sysctl hw.usb.template="${_new_template}" > /dev/null
110		err=$?
111		if [ "${err}" -ne 0 ]; then
112			warn "unable to set hw.usb.template sysctl to ${_new_template}"
113			return "${err}"
114		fi
115	fi
116}
117
118cfumass_stop()
119{
120	local err _template _new_template
121
122	remove_luns
123
124	_template=`sysctl -n hw.usb.template`
125	case "${_template}" in
126	0)
127		_new_template="-1"
128		;;
129	10)
130		_new_template="8"
131		;;
132	*)
133		warn "hw.usb.template sysctl set to neither 0 nor 10; not changing"
134		_new_template=""
135		;;
136	esac
137
138	if [ -n "${_new_template}" ]; then
139		sysctl hw.usb.template="${_new_template}" > /dev/null
140		err=$?
141		if [ "${err}" -ne 0 ]; then
142			warn "unable to set hw.usb.template sysctl to ${_new_template}"
143			return "${err}"
144		fi
145	fi
146}
147
148load_rc_config $name
149run_rc_command "$1"
150