8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / stmsboot / mpxio-upgrade
blob48df22f49511e76b2e5da80aa38605f2fe3eb860
1 #!/sbin/sh
3 # CDDL HEADER START
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.
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.
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]
20 # CDDL HEADER END
24 # Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
25 # Copyright 2016 Nexenta Systems, Inc.
28 . /lib/svc/share/fs_include.sh
29 . /lib/svc/share/net_include.sh
31 # Make sure that the essential libraries can be found.
32 LD_LIBRARY_PATH=/lib; export LD_LIBRARY_PATH
33 STMSBOOTUTIL=/lib/mpxio/stmsboot_util
34 SAVEDIR=/etc/mpxio
35 BOOTDEVICES=$SAVEDIR/boot-devices
36 RECOVERFILE=$SAVEDIR/recover_instructions
37 DEVFSADM=/usr/sbin/devfsadm
38 DUMPADM=/usr/sbin/dumpadm
39 ISROOTDEV=""
40 ISROOTDEVPATH=""
41 usrmounted=0
42 UNAME=/usr/bin/uname
43 ECHO=/usr/bin/echo
44 CAT=/usr/bin/cat
45 CP=/usr/bin/cp
46 DF=/usr/bin/df
47 LS=/usr/bin/ls
48 RM=/usr/bin/rm
49 EGREP=/usr/bin/egrep
50 SED=/usr/bin/sed
51 ZPOOL=/usr/sbin/zpool
52 AWK=/usr/bin/awk
53 MOUNT=/sbin/mount
54 UMOUNT=/sbin/mount
55 EEPROM=/usr/sbin/eeprom
56 BOOTADM=/usr/sbin/bootadm
57 SVCADM=/usr/sbin/svcadm
58 REBOOT=/usr/sbin/reboot
60 mpxio_error()
62 cecho "\nERROR: stmsboot: $1"
64 # display recovery instructions - the first call logs to the service
65 # log and the second call displays on the console.
67 shcat $RECOVERFILE
68 shcat $RECOVERFILE >/dev/msglog 2>&1
69 cecho "These instructions were also logged to the file $RECOVERFILE\n"
73 # root ("/") is already mounted read only by the kernel.
74 # Remount the root read-write.
76 mpxio_mount_root()
78 HASZFSROOT=`$DF -g / |grep zfs`
79 RVAL=""
81 # In single-user maintenance mode, we don't have a writable
82 # root partition, so we _cannot_ use devlinks. Therefore we
83 # have to do some dancing - first mount the physical path
84 # read-write, then re-run $STMSBOOTUTIL to get the real
85 # devlink mapping, and then re-mount the root slice. Of course,
86 # if we all used ZFS this wouldn't be such a pain!
87 exec < $vfstab; readvfstab /
88 # ZFS root environments should _not_ have an entry for /
89 # in their /etc/vfstab.
90 if [ -n "$special" ]; then
91 # sanity check for ZFSRoot _and_ / in /etc/vfstab
92 if [ -n "$HASZFSROOT" ]; then
93 # ERROR - this would cause a failure later
94 # so let root know about it now and provide
95 # a chance to handle it before filesystem/usr
96 cecho "stmsboot: System has ZFS Root *and* an entry for / in /etc/vfstab\nstmsboot: Please remove the / entry from /etc/vfstab and then run\n# svcadm clear mpxio-upgrade"
97 exit 1
99 ISPHYS=`echo $special |$AWK '/^\/dev\/dsk/ {print}'`;
100 if [ -z "$ISPHYS" ]; then
101 # a metadevice, /dev/vx
102 new_special=$special
103 $MOUNT -o remount,rw $new_special / >/dev/msglog 2>&1
104 else
105 new_special=`$STMSBOOTUTIL -m $special`
106 if [ "$new_special" = "NOT_MAPPED" ]; then
107 # this is a bad state to be in, exit
108 cecho "Error: Your root device is not mapped."
109 exit 1
111 checkopt "llock" $mntopts
112 mntopts='remount'
113 [ -n "$otherops" ] && mntopts="${mntopts},${otherops}"
114 RVAL=`$MOUNT -m -F $fstype -o $mntopts $new_special \
115 $mountp >/dev/msglog 2>&1`
116 # if we've got active-active paths to our rootvp and
117 # the first path returned by $STMSBOOTUTIL is not the
118 # same as the one we booted from, then we need some
119 # handwaving due to restrictions in the ufs module
120 # (see the remountfs() function in
121 # $SRC/uts/common/fs/ufs/ufs_vfsops.c)
122 if [ $? -eq 0 ]; then
123 # now re-run $STMSBOOTUTIL to get the real
124 # mapping for this device
125 new_special=`$STMSBOOTUTIL -m $special`
126 # mount root for real
127 $MOUNT -o remount,rw $new_special / \
128 >/dev/msglog 2>&1
129 else
130 for device in `$CAT $BOOTDEVICES`; do
131 new_special="/devices${device}"
132 $MOUNT -m -F $fstype -o $mntopts \
133 $new_special $mountp >/dev/msglog 2>&1
134 if [ $? -eq 0 ]; then
135 # success, break out
136 ISROOTDEVPATH=`$ECHO $device | \
137 $AWK -F":" '{print $1}'`
138 break;
140 done
141 if [ -n "$RVAL" ]; then
142 cecho "Error: Unable to remount your root device"
143 exit 1;
147 else
148 if [ -z "$HASZFSROOT" ]; then
149 cecho "stmsboot: Error: your root slice is invalid"
150 exit 1
151 else
152 cecho "stmsboot: Root is on ZFS"
158 # mount /usr read only
160 mpxio_mount_usr()
162 exec < $vfstab; readvfstab "/usr"
163 ret_val=0
164 if [ -n "$mountp" ]; then
165 case "$special" in
166 /dev/vx/*)
167 new_special=$special
170 new_special=`$STMSBOOTUTIL -m $special`
172 esac
175 # Must use -o largefiles here to ensure the read-only
176 # mount does not fail as a result of having a large
177 # file present on /usr.
179 if [ "$mntopts" = "-" ]; then
180 mntopts='ro,largefiles'
181 else
182 checkopt largefiles $mntopts
183 if [ "$option" != "largefiles" ]; then
184 mntopts="largefiles,$mntopts"
187 checkopt ro $mntopts
188 if [ "$option" != "ro" ]; then
189 mntopts="ro,$mntopts"
192 # Requesting logging on a read-only mount
193 # causes errors to be displayed, so remove
194 # "logging" from the list of options.
195 checkopt logging $mntopts
196 if [ "$option" = "logging" ]; then
197 mntopts="$otherops"
201 # In case of a manual restart of the service, mount
202 # will emit messages if /usr is already mounted.
203 # So redirect the output to /dev/null.
204 $MOUNT -m -F $fstype -o $mntopts $new_special /usr \
205 >/dev/null 2>&1
206 ret_val=$?
207 if [ $ret_val -eq 0 ]; then
208 usrmounted=1
212 return $ret_val
215 # update system dump configuration
216 update_dumpconf()
218 # Disable device-in-use checking (done in libdiskmgt).
219 # Without disabling this check, the configuration of dump device
220 # would fail as the device-in-use code incorrectly concludes that
221 # the device is in use and hence prevents configuration of the dump
222 # device.
223 NOINUSE_CHECK=1
224 export NOINUSE_CHECK
226 DUMPISZFS=`$AWK -F"=" '/DUMPADM_DEVICE/ {print $2}' /etc/dumpadm.conf|$EGREP zvol`
227 if [ -z "$DUMPISZFS" ]; then
228 set -- `$DUMPADM -u 2>&1 | $EGREP 'cannot use /dev.* as dump device'`
229 if [ -n "$4" ]; then
230 newname=`$STMSBOOTUTIL -m $4`
231 if [ $? -eq 0 ]; then
232 if $DUMPADM -d $newname > /dev/msglog 2> /dev/console; then
233 cecho "stmsboot: dump configuration \
234 has been updated."
235 else
236 mpxio_error "failed to configure \
237 the dump device.\nold \
238 dump device name: $4"
239 return 1
243 else
244 # make sure we can get to it, force zfs to load fully
245 $LS $DUMPISZFS >>/dev/null 2>&1
246 cecho "stmsboot: dump on ZFS, no dumpadm update required"
248 return 0
251 # Update bootpath for x86 here when we are enabling mpxio on root
252 update_bootpath()
254 cur_bootpath=`$STMSBOOTUTIL -b`
255 if [ $? -ne 0 ]; then
256 cecho "stmsboot: ERROR! Unable to retrieve bootpath property\n"
257 exit 1
260 # Since on x64 platforms the eeprom command doesn't update the
261 # kernel, the file /boot/solaris/bootenv.rc and the kernel's
262 # bootpath variable have a good chance of differing. We do some
263 # extra handwaving to get the correct bootpath variable setting.
265 ONDISKVER=`$AWK '/bootpath/ {print $3}' /boot/solaris/bootenv.rc|\
266 $SED -e"s,',,g"`
267 if [ "$ONDISKVER" != "$cur_bootpath" ]; then
268 cur_bootpath="$ONDISKVER"
271 NEWBOOTPATH=""
272 for path in $cur_bootpath; do
273 mapped=`$STMSBOOTUTIL -p $path`
274 if [ "$mapped" != "NOT_MAPPED" ]; then
275 if [ "$mapped" != "$path" ]; then
276 NEWBOOTPATH=`echo "$path " | \
277 $SED -e"s|$path|$mapped|"`" $NEWBOOTPATH"
278 else
279 NEWBOOTPATH="$NEWBOOTPATH $path"
282 done
283 # now strip off leading and trailing space chars
284 new_bootpath=`echo $NEWBOOTPATH`
285 $EEPROM bootpath="$new_bootpath"
286 cecho "stmsboot: bootpath has been updated"
287 cecho ""
290 # Now do the actual work
291 mpxio_main()
293 # NOTE: If the first attempt to run the service has failed due to an
294 # expected error, users should be able to manually rerun the service.
296 # First mount /usr read only. This must be done to run
297 # utilities such as fsck and devfsadm.
298 # In the case of a manual rerun of the service, mounting of /usr here
299 # fails if /usr already happens to be mounted. It is better that we
300 # do not mount /usr if already mounted, but there seems to be no
301 # apparent way to check whether /usr is mounted or not as we mount
302 # /usr without making an entry into /etc/mnttab. So instead of
303 # explicitly checking for mount failures, we just do a sanity check
304 # by looking for some file (in this case devfsadm) in /usr.
306 mpxio_mount_usr
307 if [ ! -s $DEVFSADM ]; then
308 mpxio_error "failed to mount the /usr filesystem."
309 return
312 if mpxio_mount_root; then
313 # create /dev links
314 cecho "stmsboot: configuring devices"
315 $DEVFSADM
317 if [ -n "$ISROOTDEVPATH" ]; then
318 ISROOTDEV=`$STMSBOOTUTIL -o $ISROOTDEVPATH`
321 # update /etc/vfstab to reflect device name changes
322 $STMSBOOTUTIL -u >/dev/msglog 2>&1
323 if [ $? -eq 0 ]; then
324 $CP /etc/vfstab /etc/vfstab.old
325 # handle active-active paths, where the probe order
326 # for the hba reports a different path to what the
327 # boot-device variable gives us
328 if [ -n "$ISROOTDEV" ]; then
329 ROOTDEVCHK=`grep $ISROOTDEV /etc/vfstab`
330 if [ $? -ne 0 ]; then
331 # we got a different path for root
332 exec < $SAVEDIR/vfstab.new; readvfstab /
333 FILEDEV=`$ECHO $special | \
334 $SED -e"s,/dev/dsk/,," -e"s,s[0-9]*,,"`
335 $SED -e"s,$FILEDEV,$ISROOTDEV,g" < \
336 $SAVEDIR/vfstab.new > /etc/vfstab
338 else
339 $CP $SAVEDIR/vfstab.new /etc/vfstab
341 $RM $SAVEDIR/vfstab.new
342 cecho ""
343 cecho "stmsboot: vfstab has been updated"
345 update_dumpconf
347 MACH=`$UNAME -p`
348 if [ "$MACH" = "i386" ]; then
349 # only update bootpath here for x86
350 update_bootpath
352 cecho "stmsboot: now regenerating boot archive"
353 $BOOTADM update-archive
354 else
355 mpxio_error "failed to update /etc/vfstab."
358 $SVCADM disable system/device/mpxio-upgrade
360 if [ $usrmounted -eq 1 ]; then
361 cecho "stmsboot: rebooting the system now."
362 $REBOOT
364 else
365 mpxio_error "failed to mount the root filesystem."
369 mpxio_main