1158722Sflz#!/bin/sh
2158722Sflz#
3158722Sflz# Copyright (c) 2006  The FreeBSD Project
4158722Sflz# All rights reserved.
5158722Sflz#
6158722Sflz# Redistribution and use in source and binary forms, with or without
7158722Sflz# modification, are permitted provided that the following conditions
8158722Sflz# are met:
9158722Sflz# 1. Redistributions of source code must retain the above copyright
10158722Sflz#    notice, this list of conditions and the following disclaimer.
11158722Sflz# 2. Redistributions in binary form must reproduce the above copyright
12158722Sflz#    notice, this list of conditions and the following disclaimer in the
13158722Sflz#    documentation and/or other materials provided with the distribution.
14158722Sflz#
15158722Sflz# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16158722Sflz# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17158722Sflz# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18158722Sflz# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19158722Sflz# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20158722Sflz# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21158722Sflz# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22158722Sflz# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23158722Sflz# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24158722Sflz# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25158722Sflz# SUCH DAMAGE.
26158722Sflz#
27158722Sflz# $FreeBSD$
28158722Sflz#
29158722Sflz
30158722Sflz# PROVIDE: mdconfig
31252310Shrs# REQUIRE: swap root
32158722Sflz
33158722Sflz. /etc/rc.subr
34158722Sflz
35158722Sflzname="mdconfig"
36158722Sflzstop_cmd="mdconfig_stop"
37158722Sflzstart_cmd="mdconfig_start"
38165683Syarstart_precmd='[ -n "${_mdconfig_list}" ]'
39165683Syarrequired_modules="geom_md:g_md"
40158722Sflz
41158722Sflzis_readonly()
42158722Sflz{
43158722Sflz	local _mp _ret
44158722Sflz
45158722Sflz	_mp=$1
46158722Sflz	_ret=`mount | while read _line; do
47158722Sflz		case ${_line} in
48158722Sflz		*" ${_mp} "*read-only*)
49158722Sflz			echo "yes"
50158722Sflz			;;
51208060Sdougb
52158722Sflz		*)
53158722Sflz			;;
54158722Sflz		esac;
55158722Sflz	done`
56158722Sflz
57158722Sflz	if [ -n "${_ret}" ]; then
58158722Sflz		return 0
59158722Sflz	else
60158722Sflz		return 1
61158722Sflz	fi
62158722Sflz}
63158722Sflz
64158722Sflzinit_variables()
65158722Sflz{
66158722Sflz	local _i
67158722Sflz
68158722Sflz	_fs=""
69158722Sflz	_mp=""
70158722Sflz	_dev="/dev/${_md}"
71158722Sflz	eval _config=\$mdconfig_${_md}
72158722Sflz	eval _newfs=\$mdconfig_${_md}_newfs
73158722Sflz
74158722Sflz	_type=${_config##*-t\ }
75158722Sflz	_type=${_type%%\ *}
76158722Sflz	if [ -z "${_type}" ]; then
77158722Sflz		err 1 "You need to specify \"-t <type>\" in mdconfig_${_md}"
78158722Sflz	fi
79158722Sflz
80158722Sflz	if [ "${_type}" = "vnode" ]; then
81158722Sflz		_file=${_config##*-f\ }
82158722Sflz		_file=${_file%%\ *}
83158722Sflz		if [ -z "${_file}" ]; then
84158722Sflz			err 2 "You need to specify \"-f <file>\" in mdconfig_${_md} for vnode devices"
85158722Sflz		fi
86158722Sflz		if [ "${_file}" != "${_file%.uzip}" ]; then
87158722Sflz			_dev="/dev/${_md}.uzip"
88158722Sflz		fi
89158722Sflz		for _i in `df ${_file} 2>/dev/null`; do _fs=${_i}; done
90158722Sflz	fi
91158722Sflz
92158722Sflz	# Debugging help.
93158722Sflz	debug "${_md} config: ${_config}"
94158722Sflz	debug "${_md} type: ${_type}"
95158722Sflz	debug "${_md} dev: ${_dev}"
96158722Sflz	debug "${_md} file: ${_file}"
97158722Sflz	debug "${_md} fs: ${_fs}"
98158722Sflz	debug "${_md} newfs flags: ${_newfs}"
99158722Sflz}
100158722Sflz
101158722Sflzmdconfig_start()
102158722Sflz{
103158722Sflz	local _md _mp _config _type _dev _file _fs _newfs _fsck_cmd
104158722Sflz
105158722Sflz	for _md in ${_mdconfig_list}; do
106158722Sflz		init_variables ${_md}
107158722Sflz		# Create md(4) devices of types swap, malloc and vnode if the
108158722Sflz		# file is on the root partition.
109158722Sflz		if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then
110158722Sflz			if [ "${_type}" = "vnode" ]; then
111158722Sflz				if is_readonly ${_fs}; then
112158722Sflz					warn "${_fs} is mounted read-only, skipping ${_md}."
113158722Sflz					continue
114158722Sflz				fi
115165683Syar				if [ "${_file}" != "${_file%.uzip}" ]; then
116165683Syar					load_kld -m g_uzip geom_uzip || return 3
117171956Smatteo					# sleep a bit to allow creation of /dev/mdX.uzip
118171956Smatteo					sleep 2
119165683Syar				fi
120158722Sflz			fi
121158722Sflz			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
122158722Sflz				err 3 "${_md} already exists"
123158722Sflz			fi
124158722Sflz			echo "Creating ${_md} device (${_type})."
125158722Sflz			if ! mdconfig -a ${_config} -u ${_md}; then
126158722Sflz				echo "Creating ${_md} device failed, moving on."
127158722Sflz				continue
128158722Sflz			fi
129158722Sflz			# Skip fsck for uzip devices.
130158722Sflz			if [ "${_type}" = "vnode" ]; then
131158722Sflz				if [ "${_file}" != "${_file%.uzip}" ]; then
132158722Sflz					_fsck_cmd=":"
133158722Sflz				elif checkyesno background_fsck; then
134158722Sflz					_fsck_cmd="fsck -F"
135158722Sflz				else
136158722Sflz					_fsck_cmd="fsck"
137158722Sflz				fi
138158722Sflz				if ! eval ${_fsck_cmd} -p ${_dev} >/dev/null; then
139158722Sflz					echo "Fsck failed on ${_dev}, not mounting the filesystem."
140158722Sflz					continue
141208060Sdougb
142158722Sflz				fi
143158722Sflz			else
144158722Sflz				newfs ${_newfs} ${_dev} >/dev/null
145158722Sflz			fi
146158722Sflz			if mount -d ${_dev} 2>&1 >/dev/null; then
147158722Sflz				echo "Mounting ${_dev}."
148158722Sflz				mount ${_dev}
149158722Sflz			fi
150158722Sflz		fi
151158722Sflz	done
152158722Sflz}
153158722Sflz
154158722Sflzmdconfig_stop()
155158722Sflz{
156158722Sflz	local _md _mp _config _type _dev _file _fs _newfs _i
157158722Sflz
158158722Sflz	for _md in ${_mdconfig_list}; do
159158722Sflz		init_variables ${_md}
160158722Sflz		if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then
161158722Sflz			for _i in `df ${_dev} 2>/dev/null`; do _mp=${_i}; done
162158722Sflz			if [ -z "${_mp}" -o "${_mp}" != "${_mp%%%}" ]; then
163158722Sflz				echo "Device ${_dev} isn't mounted."
164158722Sflz			else
165158722Sflz				echo "Umounting ${_dev}."
166158722Sflz				umount ${_dev}
167158722Sflz			fi
168158722Sflz			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
169158722Sflz				echo "Destroying ${_md}."
170158722Sflz				mdconfig -d -u ${_md}
171158722Sflz			fi
172158722Sflz		fi
173158722Sflz	done
174158722Sflz}
175158722Sflz
176158722Sflz_mdconfig_cmd="$1"
177158722Sflzif [ $# -gt 0 ]; then
178158722Sflz        shift
179158722Sflzfi
180158722Sflz[ -n "$*" ] && _mdconfig_list="$*"
181158722Sflz
182158722Sflzload_rc_config $name
183158722Sflz
184158722Sflzif [ -z "${_mdconfig_list}" ]; then
185264438Sdteske	for _mdconfig_config in `list_vars mdconfig_md[0-9]\* |
186264438Sdteske		sort_lite -nk1.12`
187264438Sdteske	do
188264438Sdteske		_mdconfig_unit=${_mdconfig_config#mdconfig_md}
189264438Sdteske		_mdconfig_list="$_mdconfig_list md$_mdconfig_unit"
190158722Sflz	done
191264438Sdteske	_mdconfig_list="${_mdconfig_list# }"
192158722Sflzfi
193208060Sdougb
194158722Sflzrun_rc_command "${_mdconfig_cmd}"
195