mdconfig revision 160669
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 160669 2006-07-25 17:19:00Z pjd $
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	# If there are no devices return before loading geom_md.ko.
107	if [ -z "${_mdconfig_list}" ]; then
108		return
109	fi
110
111	kldstat -q -m g_md || kldload geom_md || err 1 "geom_md failed to load."
112
113	for _md in ${_mdconfig_list}; do
114		init_variables ${_md}
115		# Create md(4) devices of types swap, malloc and vnode if the
116		# file is on the root partition.
117		if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then
118			if [ "${_type}" = "vnode" ]; then
119				if is_readonly ${_fs}; then
120					warn "${_fs} is mounted read-only, skipping ${_md}."
121					continue
122				fi
123			fi
124			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
125				err 3 "${_md} already exists"
126			fi
127			echo "Creating ${_md} device (${_type})."
128			if ! mdconfig -a ${_config} -u ${_md}; then
129				echo "Creating ${_md} device failed, moving on."
130				continue
131			fi
132			# Skip fsck for uzip devices.
133			if [ "${_type}" = "vnode" ]; then
134				if [ "${_file}" != "${_file%.uzip}" ]; then
135					_fsck_cmd=":"
136				elif checkyesno background_fsck; then
137					_fsck_cmd="fsck -F"
138				else
139					_fsck_cmd="fsck"
140				fi
141				if ! eval ${_fsck_cmd} -p ${_dev} >/dev/null; then
142					echo "Fsck failed on ${_dev}, not mounting the filesystem."
143					continue
144					
145				fi
146			else
147				newfs ${_newfs} ${_dev} >/dev/null
148			fi
149			if mount -d ${_dev} 2>&1 >/dev/null; then
150				echo "Mounting ${_dev}."
151				mount ${_dev}
152			fi
153		fi
154	done
155}
156
157mdconfig_stop()
158{
159	local _md _mp _config _type _dev _file _fs _newfs _i
160
161	for _md in ${_mdconfig_list}; do
162		init_variables ${_md}
163		if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then
164			for _i in `df ${_dev} 2>/dev/null`; do _mp=${_i}; done
165			if [ -z "${_mp}" -o "${_mp}" != "${_mp%%%}" ]; then
166				echo "Device ${_dev} isn't mounted."
167			else
168				echo "Umounting ${_dev}."
169				umount ${_dev}
170			fi
171			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
172				echo "Destroying ${_md}."
173				mdconfig -d -u ${_md}
174			fi
175		fi
176	done
177}
178
179_mdconfig_cmd="$1"
180if [ $# -gt 0 ]; then
181        shift
182fi
183[ -n "$*" ] && _mdconfig_list="$*"
184
185load_rc_config $name
186
187_mdconfig_unit=0
188if [ -z "${_mdconfig_list}" ]; then
189	while :; do
190		eval _mdconfig_config=\$mdconfig_md${_mdconfig_unit}
191		if [ -z "${_mdconfig_config}" ]; then
192			break
193		else
194			_mdconfig_list="${_mdconfig_list}${_mdconfig_list:+ }md${_mdconfig_unit}"
195			_mdconfig_unit=$((${_mdconfig_unit} + 1))
196		fi
197	done
198fi
199	
200run_rc_command "${_mdconfig_cmd}"
201