mdconfig2 revision 208060
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/mdconfig2 208060 2010-05-14 04:53:57Z dougb $
28#
29
30# PROVIDE: mdconfig2
31# REQUIRE: mountcritremote
32# BEFORE: SERVERS
33
34. /etc/rc.subr
35
36name="mdconfig2"
37stop_cmd="mdconfig2_stop"
38start_cmd="mdconfig2_start"
39start_precmd='[ -n "${_mdconfig2_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	_mounted="no"
72	_dev="/dev/${_md}"
73	eval _config=\$mdconfig_${_md}
74	eval _owner=\$mdconfig_${_md}_owner
75	eval _perms=\$mdconfig_${_md}_perms
76	eval _files=\$mdconfig_${_md}_files
77	eval _populate=\$mdconfig_${_md}_cmd
78
79	_type=${_config##*-t\ }
80	_type=${_type%%\ *}
81	if [ -z "${_type}" ]; then
82		err 1 "You need to specify \"-t <type>\" in mdconfig_${_md}"
83	fi
84
85	if [ "${_type}" = "vnode" ]; then
86		_file=${_config##*-f\ }
87		_file=${_file%%\ *}
88		if [ -z "${_file}" ]; then
89			err 2 "You need to specify \"-f <file>\" in mdconfig_${_md} for vnode devices"
90		fi
91
92		if [ "${_file}" != "${_file%.uzip}" ]; then
93			_dev="/dev/${_md}.uzip"
94		fi
95		for _i in `df ${_file} 2>/dev/null`; do _fs=${_i}; done
96	fi
97
98	# Debugging help.
99	debug "${_md} config: ${_config}"
100	debug "${_md} type: ${_type}"
101	debug "${_md} dev: ${_dev}"
102	debug "${_md} file: ${_file}"
103	debug "${_md} fs: ${_fs}"
104	debug "${_md} owner: ${_owner}"
105	debug "${_md} perms: ${_perms}"
106	debug "${_md} files: ${_files}"
107	debug "${_md} populate cmd: ${_populate}"
108}
109
110mdconfig2_start()
111{
112	local _md _fs _mp _mounted _dev _config _type _file _owner _perms _files _populate _fsck_cmd _i
113
114	for _md in ${_mdconfig2_list}; do
115		init_variables ${_md}
116		if [ ! -r ${_file} ]; then
117			err 3 "${_file} doesn't exist"
118			continue
119		fi
120		# First pass: create md(4) vnode devices from files stored on
121		# non-root partition. Swap and malloc md(4) devices have already
122		# been created.
123		if [ "${_type}" = "vnode" -a "${_fs}" != "/" ]; then
124			if [ "${_file}" != "${_file%.uzip}" ]; then
125				load_kld -m g_uzip geom_uzip || return 3
126			fi
127			if is_readonly ${_fs}; then
128				warn "${_fs} is mounted read-only, skipping ${_md}."
129				continue
130			fi
131			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
132				err 3 "${_md} already exists"
133			fi
134			echo "Creating ${_md} device (${_type})."
135			if ! mdconfig -a ${_config} -u ${_md}; then
136				echo "Creating ${_md} device failed, moving on."
137				continue
138			fi
139			# Skip fsck for uzip devices.
140			if [ "${_file}" != "${_file%.uzip}" ]; then
141				_fsck_cmd=":"
142			elif checkyesno background_fsck; then
143				_fsck_cmd="fsck -F"
144			else
145				_fsck_cmd="fsck"
146			fi
147			if ! eval ${_fsck_cmd} -p ${_dev} >/dev/null; then
148				echo "Fsck failed on ${_dev}, not mounting the filesystem."
149				continue
150			fi
151			if mount -d ${_dev} >/dev/null 2>&1; then
152				echo "Mounting ${_dev}."
153				mount ${_dev}
154			fi
155		fi
156
157		for _i in `df ${_dev} 2>/dev/null`; do _mp=${_i}; done
158		if [ ! -z "${_mp}" -a "${_mp}" = "${_mp%%%}" ]; then
159			_mounted="yes"
160		fi
161
162		if checkyesno _mounted; then
163			# Second pass: change permissions and ownership.
164			[ -z "${_owner}" ] || chown -f ${_owner} ${_dev} ${_mp}
165			[ -z "${_perms}" ] || chmod -f ${_perms} ${_dev} ${_mp}
166
167			# Third pass: populate with foreign files.
168			if [ -n "${_files}" -o -n "${_populate}" ]; then
169				echo "Populating ${_dev}."
170			fi
171			if [ -n "${_files}" ]; then
172				cp -Rp ${_files} ${_mp}
173			fi
174			if [ -n "${_populate}" ]; then
175				eval ${_populate}
176			fi
177		fi
178	done
179}
180
181mdconfig2_stop()
182{
183	local _md _fs _mp _mounted _dev _config _type _file _owner _perms _files _populate
184
185	for _md in ${_mdconfig2_list}; do
186		init_variables ${_md}
187		if [ "${_type}" = "vnode" ]; then
188			for i in `df ${_dev} 2>/dev/null`; do _mp=$i; done
189			if [ ! -r "${_file}" -o "${_fs}" = "/" ]; then
190				continue
191			fi
192			if [ -z "${_mp}" -o "${_mp}" != "${_mp%%%}" ]; then
193				echo "Device ${_dev} isn't mounted."
194			else
195				echo "Umounting ${_dev}."
196				umount ${_dev}
197			fi
198			if mdconfig -l -u ${_md} >/dev/null 2>&1; then
199				echo "Destroying ${_md}."
200				mdconfig -d -u ${_md}
201			fi
202		fi
203	done
204}
205
206_mdconfig2_cmd="$1"
207if [ $# -gt 0 ]; then
208        shift
209fi
210[ -n "$*" ] && _mdconfig2_list="$*"
211
212load_rc_config $name
213
214_mdconfig2_unit=0
215if [ -z "${_mdconfig2_list}" ]; then
216	while :; do
217		eval _mdconfig2_config=\$mdconfig_md${_mdconfig2_unit}
218		if [ -z "${_mdconfig2_config}" ]; then
219			break
220		else
221			_mdconfig2_list="${_mdconfig2_list}${_mdconfig2_list:+ }md${_mdconfig2_unit}"
222			_mdconfig2_unit=$((${_mdconfig2_unit} + 1))
223		fi
224	done
225fi
226
227run_rc_command "${_mdconfig2_cmd}"
228