mdconfig revision 165683
1#!/bin/sh
2#
3# Copyright (c) 2006  The FreeBSD Project
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: head/etc/rc.d/mdconfig 165683 2006-12-31 10:37:18Z yar $
28#
29
30# PROVIDE: mdconfig
31# REQUIRE: localswap
32# BEFORE: mountcritlocal
33
34. /etc/rc.subr
35
36name="mdconfig"
37stop_cmd="mdconfig_stop"
38start_cmd="mdconfig_start"
39start_precmd='[ -n "${_mdconfig_list}" ]'
40required_modules="geom_md:g_md"
41
42is_readonly()
43{
44	local _mp _ret
45
46	_mp=$1
47	_ret=`mount | while read _line; do
48		case ${_line} in
49		*" ${_mp} "*read-only*)
50			echo "yes"
51			;;
52		
53		*)
54			;;
55		esac;
56	done`
57
58	if [ -n "${_ret}" ]; then
59		return 0
60	else
61		return 1
62	fi
63}
64
65init_variables()
66{
67	local _i
68
69	_fs=""
70	_mp=""
71	_dev="/dev/${_md}"
72	eval _config=\$mdconfig_${_md}
73	eval _newfs=\$mdconfig_${_md}_newfs
74
75	_type=${_config##*-t\ }
76	_type=${_type%%\ *}
77	if [ -z "${_type}" ]; then
78		err 1 "You need to specify \"-t <type>\" in mdconfig_${_md}"
79	fi
80
81	if [ "${_type}" = "vnode" ]; then
82		_file=${_config##*-f\ }
83		_file=${_file%%\ *}
84		if [ -z "${_file}" ]; then
85			err 2 "You need to specify \"-f <file>\" in mdconfig_${_md} for vnode devices"
86		fi
87		if [ "${_file}" != "${_file%.uzip}" ]; then
88			_dev="/dev/${_md}.uzip"
89		fi
90		for _i in `df ${_file} 2>/dev/null`; do _fs=${_i}; done
91	fi
92
93	# Debugging help.
94	debug "${_md} config: ${_config}"
95	debug "${_md} type: ${_type}"
96	debug "${_md} dev: ${_dev}"
97	debug "${_md} file: ${_file}"
98	debug "${_md} fs: ${_fs}"
99	debug "${_md} newfs flags: ${_newfs}"
100}
101
102mdconfig_start()
103{
104	local _md _mp _config _type _dev _file _fs _newfs _fsck_cmd
105
106	for _md in ${_mdconfig_list}; do
107		init_variables ${_md}
108		# Create md(4) devices of types swap, malloc and vnode if the
109		# file is on the root partition.
110		if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then
111			if [ "${_type}" = "vnode" ]; then
112				if is_readonly ${_fs}; then
113					warn "${_fs} is mounted read-only, skipping ${_md}."
114					continue
115				fi
116				if [ "${_file}" != "${_file%.uzip}" ]; then
117					load_kld -m g_uzip geom_uzip || return 3
118				fi
119			fi
120			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
121				err 3 "${_md} already exists"
122			fi
123			echo "Creating ${_md} device (${_type})."
124			if ! mdconfig -a ${_config} -u ${_md}; then
125				echo "Creating ${_md} device failed, moving on."
126				continue
127			fi
128			# Skip fsck for uzip devices.
129			if [ "${_type}" = "vnode" ]; then
130				if [ "${_file}" != "${_file%.uzip}" ]; then
131					_fsck_cmd=":"
132				elif checkyesno background_fsck; then
133					_fsck_cmd="fsck -F"
134				else
135					_fsck_cmd="fsck"
136				fi
137				if ! eval ${_fsck_cmd} -p ${_dev} >/dev/null; then
138					echo "Fsck failed on ${_dev}, not mounting the filesystem."
139					continue
140					
141				fi
142			else
143				newfs ${_newfs} ${_dev} >/dev/null
144			fi
145			if mount -d ${_dev} 2>&1 >/dev/null; then
146				echo "Mounting ${_dev}."
147				mount ${_dev}
148			fi
149		fi
150	done
151}
152
153mdconfig_stop()
154{
155	local _md _mp _config _type _dev _file _fs _newfs _i
156
157	for _md in ${_mdconfig_list}; do
158		init_variables ${_md}
159		if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then
160			for _i in `df ${_dev} 2>/dev/null`; do _mp=${_i}; done
161			if [ -z "${_mp}" -o "${_mp}" != "${_mp%%%}" ]; then
162				echo "Device ${_dev} isn't mounted."
163			else
164				echo "Umounting ${_dev}."
165				umount ${_dev}
166			fi
167			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
168				echo "Destroying ${_md}."
169				mdconfig -d -u ${_md}
170			fi
171		fi
172	done
173}
174
175_mdconfig_cmd="$1"
176if [ $# -gt 0 ]; then
177        shift
178fi
179[ -n "$*" ] && _mdconfig_list="$*"
180
181load_rc_config $name
182
183_mdconfig_unit=0
184if [ -z "${_mdconfig_list}" ]; then
185	while :; do
186		eval _mdconfig_config=\$mdconfig_md${_mdconfig_unit}
187		if [ -z "${_mdconfig_config}" ]; then
188			break
189		else
190			_mdconfig_list="${_mdconfig_list}${_mdconfig_list:+ }md${_mdconfig_unit}"
191			_mdconfig_unit=$((${_mdconfig_unit} + 1))
192		fi
193	done
194fi
195	
196run_rc_command "${_mdconfig_cmd}"
197