xref: /illumos-gate/usr/src/cmd/stmsboot/mpxio-upgrade (revision 4e93fb0f6383eaac21897dcdae56b87118131e4d)
1#!/sbin/sh
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22#
23# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26#ident	"%Z%%M%	%I%	%E% SMI"
27
28. /lib/svc/share/fs_include.sh
29. /lib/svc/share/net_include.sh
30
31# Make sure that the essential libraries can be found.
32LD_LIBRARY_PATH=/lib; export LD_LIBRARY_PATH
33STMSBOOTUTIL=/lib/mpxio/stmsboot_util
34FPCONF=/kernel/drv/fp.conf
35SAVEDIR=/etc/mpxio
36RECOVERFILE=$SAVEDIR/recover_instructions
37DEVFSADM=/usr/sbin/devfsadm
38METADEVADM=/usr/sbin/metadevadm
39usrmounted=0
40MACH=`/usr/bin/uname -p`
41
42# map $special and $fsckdev
43mpxio_mapdev()
44{
45	new_special=`$STMSBOOTUTIL -m $special`
46	if [ $? -eq 0 ]; then
47		special=$new_special
48	fi
49
50	new_fsckdev=`$STMSBOOTUTIL -m $fsckdev`
51	if [ $? -eq 0 ]; then
52		fsckdev=$new_fsckdev
53	fi
54}
55
56mpxio_error()
57{
58	cecho "\nERROR: stmsboot: $1"
59	#
60	# display recovery instructions - the first call logs to the service
61	# log and the second call displays on the console.
62	#
63	shcat $RECOVERFILE
64	shcat $RECOVERFILE >/dev/msglog 2>&1
65	cecho "These instructions were also logged to the file $RECOVERFILE\n"
66}
67
68#
69# root ("/") is already mounted read only by the kernel.
70# Remount the root read-write.
71#
72mpxio_mount_root()
73{
74	exec < $vfstab; readvfstab /
75	mpxio_mapdev
76
77	checkopt "llock" $mntopts
78	mntopts='remount'
79	[ -n "$otherops" ] && mntopts="${mntopts},${otherops}"
80	/sbin/mount -m -F $fstype -o $mntopts $special $mountp \
81>/dev/msglog 2>&1
82}
83
84#
85# mount /usr read only
86#
87mpxio_mount_usr()
88{
89	exec < $vfstab; readvfstab "/usr"
90	ret_val=0
91	if [ -n "$mountp" ]; then
92		mpxio_mapdev
93		if [ "$fstype" = cachefs ]; then
94			# Mount read-only without the cache.
95			case "$mntopts" in
96			*backfstype=nfs*)
97				cfsbacktype=nfs
98				;;
99			*backfstype=hsfs*)
100				cfsbacktype=hsfs
101				;;
102			*)
103				cecho 'stmsboot: invalid vfstab entry for /usr'
104				cfsbacktype=nfs
105				;;
106			esac
107			# see the comment below for /dev/null
108			/sbin/mount -m -F $cfsbacktype -o ro $special $mountp \
109>/dev/null 2>&1
110			ret_val=$?
111		else
112			#
113			# Must use -o largefiles here to ensure the read-only
114			# mount does not fail as a result of having a large
115			# file present on /usr.
116			#
117			if [ "x$mntopts" = x- ]; then
118				mntopts='ro,largefiles'
119			else
120				checkopt largefiles $mntopts
121				if [ "x$option" != xlargefiles ]; then
122					mntopts="largefiles,$mntopts"
123				fi
124
125				checkopt ro $mntopts
126				if [ "x$option" != xro ]; then
127					mntopts="ro,$mntopts"
128				fi
129
130				#
131				# Requesting logging on a read-only mount
132				# causes errors to be displayed, so remove
133				# "logging" from the list of options.
134				#
135
136				checkopt logging $mntopts
137				if [ "x$option" = xlogging ]; then
138					mntopts="$otherops"
139				fi
140			fi
141
142			#
143			# In case of a manual restart of the service, mount
144			# will emit messages if /usr is already mounted.
145			# So redirect the output to /dev/null.
146			#
147			/sbin/mount -m -F $fstype -o $mntopts $special /usr \
148>/dev/null 2>&1
149			ret_val=$?
150		fi
151		if [ $ret_val -eq 0 ]; then
152			usrmounted=1
153		fi
154	fi
155
156	return $ret_val
157}
158
159# update system dump configuration
160update_dumpconf()
161{
162	#
163	# Disable device-in-use checking (done in libdiskmgt).
164	# Without disabling this check, the configuration of dump device
165	# would fail as the device-in-use code incorrectly concludes that
166	# the device is in use and hence prevents configuration of the dump
167	# device.
168	#
169	NOINUSE_CHECK=1
170	export NOINUSE_CHECK
171
172	set -- `dumpadm -u 2>&1 | egrep 'cannot use /dev.* as dump device'`
173	if [ "x$4" != x ]; then
174		newname=`$STMSBOOTUTIL -M $4`
175		if [ $? -eq 0 ]; then
176			if dumpadm -d $newname > /dev/null; then
177				cecho "stmsboot: dump configuration has been \
178updated."
179			else
180				mpxio_error "failed to configure $newname as \
181the dump device.\nold dump device name: $4"
182				return 1
183			fi
184		fi
185	fi
186	return 0
187}
188
189# Update bootpath for x86 here when we are enabling mpxio on root
190update_bootpath()
191{
192	cur_bootpath=`eeprom bootpath | sed 's/bootpath=[ 	]*//g' | sed 's/[ 	].*//'`
193	# only take care of phci-based path here
194	echo $cur_bootpath | egrep -s "/fp@.*/disk@.*"
195
196	if [ $? -eq 0 ]; then
197		new_bootpath=`$STMSBOOTUTIL -m /devices$cur_bootpath`
198		if [ $? -eq 0 -a "x$new_bootpath" != "x" ]; then
199			# stmsboot_util -m phci-based path got mapped path back means
200			# mpxio is enabled on bootpath
201			new_bootpath=`echo $new_bootpath|sed "s/.*\/devices//"`
202			/usr/sbin/eeprom bootpath=$new_bootpath
203			cecho "stmsboot: bootpath has been updated"
204
205			/sbin/bootadm update-archive
206		fi
207	fi
208}
209
210#
211# do the actual work
212#
213mpxio_main()
214{
215	#
216	# NOTE: If the first attempt to run the service has failed due to an
217	# expected error, users should be able to manually rerun the service.
218	#
219	# First mount /usr read only. This must be done to run
220	# utilities such as fsck and devfsadm.
221	# In the case of a manual rerun of the service, mounting of /usr here
222	# fails if /usr already happens to be mounted. It is better that we
223	# do not mount /usr if already mounted, but there seems to be no
224	# apparent way to check whether /usr is mounted or not as we mount
225	# /usr without making an entry into /etc/mnttab. So instead of
226	# explicitly checking for mount failures, we just do a sanity check
227	# by looking for some file (in this case devfsadm) in /usr.
228	#
229	mpxio_mount_usr
230	if [ ! -s $DEVFSADM ]; then
231		mpxio_error "failed to mount the /usr filesystem."
232		return
233	fi
234
235	if mpxio_mount_root; then
236		# create /dev links
237		cecho "stmsboot: configuring devices"
238		$DEVFSADM
239
240		# update /etc/vfstab to reflect device name changes
241		if $STMSBOOTUTIL -u >/dev/msglog 2>&1; then
242			if update_dumpconf; then
243				# update svm configuration to reflect new names
244				if [ -s /kernel/drv/md.conf ] && \
245				    [ -x $METADEVADM ]; then
246					$METADEVADM -r >/dev/msglog 2>&1
247				fi
248			fi
249			if [ "x$MACH" = "xi386" ]; then
250				# only update bootpath here for x86
251				update_bootpath
252			fi
253		else
254			mpxio_error "failed to update /etc/vfstab."
255		fi
256
257		/usr/sbin/svcadm disable system/device/mpxio-upgrade
258
259		/usr/sbin/reboot
260	else
261		mpxio_error "failed to mount the root filesystem."
262		if [ $usrmounted -eq 1 ]; then
263			/sbin/umount /usr
264		fi
265	fi
266}
267
268mpxio_main
269