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