mdconfig revision 158723
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 158723 2006-05-18 16:04:56Z flz $
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"
39
40is_readonly()
41{
42	local _mp _ret
43
44	_mp=$1
45	_ret=`mount | while read _line; do
46		case ${_line} in
47		*" ${_mp} "*read-only*)
48			echo "yes"
49			;;
50		
51		*)
52			;;
53		esac;
54	done`
55
56	if [ -n "${_ret}" ]; then
57		return 0
58	else
59		return 1
60	fi
61}
62
63init_variables()
64{
65	local _i
66
67	_fs=""
68	_mp=""
69	_dev="/dev/${_md}"
70	eval _config=\$mdconfig_${_md}
71	eval _newfs=\$mdconfig_${_md}_newfs
72
73	_type=${_config##*-t\ }
74	_type=${_type%%\ *}
75	if [ -z "${_type}" ]; then
76		err 1 "You need to specify \"-t <type>\" in mdconfig_${_md}"
77	fi
78
79	if [ "${_type}" = "vnode" ]; then
80		_file=${_config##*-f\ }
81		_file=${_file%%\ *}
82		if [ -z "${_file}" ]; then
83			err 2 "You need to specify \"-f <file>\" in mdconfig_${_md} for vnode devices"
84		fi
85		if [ "${_file}" != "${_file%.uzip}" ]; then
86			# Load geom_uzip kernel module if needed
87			kldstat -q -m g_uzip || kldload geom_uzip || err 1 "geom_uzip failed to load."
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	kldstat -q -m g_md || kldload geom_md || err 1 "geom_md failed to load."
107
108	for _md in ${_mdconfig_list}; do
109		init_variables ${_md}
110		# Create md(4) devices of types swap, malloc and vnode if the
111		# file is on the root partition.
112		if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then
113			if [ "${_type}" = "vnode" ]; then
114				if is_readonly ${_fs}; then
115					warn "${_fs} is mounted read-only, skipping ${_md}."
116					continue
117				fi
118			fi
119			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
120				err 3 "${_md} already exists"
121			fi
122			echo "Creating ${_md} device (${_type})."
123			if ! mdconfig -a ${_config} -u ${_md}; then
124				echo "Creating ${_md} device failed, moving on."
125				continue
126			fi
127			# Skip fsck for uzip devices.
128			if [ "${_type}" = "vnode" ]; then
129				if [ "${_file}" != "${_file%.uzip}" ]; then
130					_fsck_cmd=":"
131				elif checkyesno background_fsck; then
132					_fsck_cmd="fsck -F"
133				else
134					_fsck_cmd="fsck"
135				fi
136				if ! eval ${_fsck_cmd} -p ${_dev} >/dev/null; then
137					echo "Fsck failed on ${_dev}, not mounting the filesystem."
138					continue
139					
140				fi
141			else
142				newfs ${_newfs} ${_dev} >/dev/null
143			fi
144			if mount -d ${_dev} 2>&1 >/dev/null; then
145				echo "Mounting ${_dev}."
146				mount ${_dev}
147			fi
148		fi
149	done
150}
151
152mdconfig_stop()
153{
154	local _md _mp _config _type _dev _file _fs _newfs _i
155
156	for _md in ${_mdconfig_list}; do
157		init_variables ${_md}
158		if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then
159			for _i in `df ${_dev} 2>/dev/null`; do _mp=${_i}; done
160			if [ -z "${_mp}" -o "${_mp}" != "${_mp%%%}" ]; then
161				echo "Device ${_dev} isn't mounted."
162			else
163				echo "Umounting ${_dev}."
164				umount ${_dev}
165			fi
166			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
167				echo "Destroying ${_md}."
168				mdconfig -d -u ${_md}
169			fi
170		fi
171	done
172}
173
174_mdconfig_cmd="$1"
175if [ $# -gt 0 ]; then
176        shift
177fi
178[ -n "$*" ] && _mdconfig_list="$*"
179
180load_rc_config $name
181
182_mdconfig_unit=0
183if [ -z "${_mdconfig_list}" ]; then
184	while :; do
185		eval _mdconfig_config=\$mdconfig_md${_mdconfig_unit}
186		if [ -z "${_mdconfig_config}" ]; then
187			break
188		else
189			_mdconfig_list="${_mdconfig_list}${_mdconfig_list:+ }md${_mdconfig_unit}"
190			_mdconfig_unit=$((${_mdconfig_unit} + 1))
191		fi
192	done
193fi
194	
195run_rc_command "${_mdconfig_cmd}"
196