1 #!/bin/ksh -p
   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 #
  24 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  25 # Use is subject to license terms.
  26 #
  27 
  28 PATH="/usr/bin:/usr/sbin:${PATH}"; export PATH
  29 ALT_ROOT=
  30 
  31 while getopts R: OPT 2>/dev/null
  32 do
  33         case $OPT in
  34         R)      ALT_ROOT="$OPTARG"
  35                 ;;
  36         ?)      echo "Usage: ${0##*/}: [-R \<root\>]"
  37                 ;;
  38         esac
  39 done
  40 
  41 ARCH=`uname -p`
  42 
  43 is_pcfs_boot=yes
  44 is_zfs_boot=no
  45 
  46 check_pcfs_boot()
  47 {
  48         bootdev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | grep pcfs \
  49             | grep "[       ]/stubboot[      ]" | /usr/xpg4/bin/awk '{print $1}'`
  50         if [ X"$bootdev" = "X" ]; then
  51                 is_pcfs_boot=no
  52         fi
  53 }
  54 
  55 check_zfs_boot()
  56 {
  57         if [ -f "$ALT_ROOT"/etc/lu/GRUB_slice ]; then
  58                 dev=`grep '^PHYS_SLICE=' "$ALT_ROOT"/etc/lu/GRUB_slice |
  59                     cut -d= -f2`
  60                 if [ "`fstyp $dev`" = "zfs" ]; then
  61                         is_zfs_boot=yes
  62                 fi
  63         else
  64                 rootfstype=`df -n ${ALT_ROOT:-/} | awk '{print $3}'`
  65                 if [ "$rootfstype" = "zfs" ]; then
  66                         is_zfs_boot=yes
  67                 fi
  68                         
  69         fi
  70 }
  71 
  72 #
  73 # Detect SVM root and return the list of raw devices under the mirror
  74 #
  75 get_rootdev_list()
  76 {
  77         if [ -f "$ALT_ROOT"/etc/lu/GRUB_slice ]; then
  78                 dev=`grep '^PHYS_SLICE' "$ALT_ROOT"/etc/lu/GRUB_slice |
  79                     cut -d= -f2`
  80                 if [ "$is_zfs_boot" = "yes" ]; then
  81                         fstyp -a "$dev" | grep 'path: ' | grep -v phys_path: | 
  82                             cut -d"'" -f2 | sed 's+/dsk/+/rdsk/+'
  83                 else
  84                         echo "$dev"
  85                 fi
  86                 return
  87         elif [ "$is_zfs_boot" = "yes" ]; then
  88                 rootpool=`df -k ${ALT_ROOT:-/} | tail +2 | cut -d/ -f1`
  89                 rootdevlist=`LC_ALL=C zpool iostat -v "$rootpool" | tail +5 |
  90                     egrep -v "mirror|spare|replacing" |
  91                     sed -n -e '/--/q' -e p | awk '{print $1}'`
  92         else
  93                 metadev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | \
  94                     grep "[      ]/[    ]" | /usr/xpg4/bin/awk '{print $2}'`
  95                 if [[ $metadev = /dev/rdsk/* ]]; then
  96                         rootdevlist=`basename "$metadev"`
  97                 elif [[ $metadev = /dev/md/rdsk/* ]]; then
  98                         metavol=`basename "$metadev"`
  99                         rootdevlist=`metastat -p $metavol |\
 100                             grep -v "^$metavol[  ]" | /usr/xpg4/bin/awk '{print $4}'`
 101                 fi
 102         fi
 103         for rootdev in $rootdevlist
 104         do
 105                 echo /dev/rdsk/`basename $rootdev`
 106         done
 107 }
 108 
 109 #
 110 # multiboot: install grub on the boot slice
 111 #
 112 install_grub()
 113 {
 114         # Stage 2 blocks must remain untouched
 115         STAGE1="$ALT_ROOT"/boot/grub/stage1
 116         STAGE2="$ALT_ROOT"/boot/grub/stage2
 117 
 118         if [ $is_pcfs_boot = yes ]; then
 119                 #
 120                 # Note: /stubboot/boot/grub/stage2 must stay untouched.
 121                 #
 122                 mkdir -p "$ALT_ROOT"/stubboot/boot/grub
 123                 cp "$ALT_ROOT"/boot/grub/menu.lst "$ALT_ROOT"/stubboot/boot/grub
 124                 bootdev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | grep pcfs | \
 125                         grep "[  ]/stubboot[    ]" | /usr/xpg4/bin/awk '{print $1}'`
 126                 rpcfsdev=`echo "$bootdev" | sed -e "s/dev\/dsk/dev\/rdsk/"`
 127                 if [ X"$rpcfsdev" != X ]; then
 128                         print "Installing grub on $rpcfsdev"
 129                         "$ALT_ROOT"/sbin/installgrub $STAGE1 $STAGE2 $rpcfsdev
 130                 fi
 131         fi
 132 
 133         grubdevlist=`get_rootdev_list`
 134         zfsarg=""
 135         if [ "$is_zfs_boot" = "yes" ]; then
 136                 zfsarg="-Z"
 137         fi
 138 
 139         for rootdev in $grubdevlist
 140         do
 141                 if [ X"$rpcfsdev" != X ]; then
 142                         echo "create GRUB menu in "$ALT_ROOT"/stubboot"
 143                         "$ALT_ROOT"/sbin/bootadm update-menu $zfsarg\
 144                             -R "$ALT_ROOT"/stubboot -o $rootdev,"$ALT_ROOT"
 145                 else
 146                         echo "Creating GRUB menu in ${ALT_ROOT:-/}"
 147                         $ALT_ROOT/sbin/bootadm update-menu -R ${ALT_ROOT:-/} \
 148                             $zfsarg -o $rootdev
 149                 fi
 150                 print "Installing grub on $rootdev"
 151                 "$ALT_ROOT"/sbin/installgrub $STAGE1 $STAGE2 $rootdev
 152         done
 153 }
 154 
 155 if [ -f "$ALT_ROOT"/platform/i86pc/multiboot -a "$ARCH" = i386 ] ; then
 156         check_pcfs_boot
 157         check_zfs_boot
 158         install_grub
 159 fi
 160 
 161 exit 0