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