#!/bin/sh rootUserRequired() { # Only the root user can run the script if [ "`/usr/bin/id | /usr/bin/cut -c1-5`" != "uid=0" ] ; then echo "You must be the root user to run `basename $0`." exit 1 fi } checkDiskSuiteInstallation() { for FILE in /usr/sbin/metadb /usr/sbin/metainit /usr/sbin/metaroot do if [ ! -x $FILE ] ; then echo "DiskSuite must be installed to run `basename $0`." exit 1 fi done } determineBootpath() { # Determine the Solaris boot disk in cxtxdx format. BOOTPATH=`prtconf -pv | grep bootpath | tr -d "'" | awk '{print $2}'` if [ -n "`echo $BOOTPATH | grep "/disk"`" ] ; then # The bootpath contains "disk," but the /devices block device contains # either "sd" or "ssd" BOOTPATH=`echo $BOOTPATH | sed 's/disk@//'` BOOT_DISK=`ls -l /dev/dsk | sed -e 's/ssd@//' -e 's/sd@//' \ | grep "$BOOTPATH" 2>/dev/null | awk '{print $9}' | sed 's/s[0-7]//'` else BOOT_DISK=`ls -l /dev/dsk | grep "$BOOTPATH" 2>/dev/null | \ awk '{print $9}' | sed 's/s[0-7]//'` fi if [ -n "$BOOT_DISK" ] ; then echo "Your boot disk is ${BOOT_DISK}." else echo "Unable to determine logical boot disk." fi } findMirrorCandidates() { BOOT_DISK_GEOMETRY=`prtvtoc /dev/dsk/${BOOT_DISK}s2 2>/dev/null | egrep "bytes/sector|sectors/track|tracks/cylinder|sectors/cylinder|cylinders|accessible cylinders" | awk '{print $2}' | tr '\n' '\t'` # Find disks with matching geometry for DISK in `iostat -En | egrep "^c[0-9]+t[0-9]+d[0-9]+" | awk '{print $1}' | grep -v $BOOT_DISK` do DISK_GEOMETRY=`prtvtoc /dev/dsk/${DISK}s2 2>/dev/null | egrep "bytes/sector|sectors/track|tracks/cylinder|sectors/cylinder|cylinders|accessible cylinders" | awk '{print $2}' | tr '\n' '\t'` if [ "$DISK_GEOMETRY" = "$BOOT_DISK_GEOMETRY" ] ; then [ -z "$MIRROR_CANDIDATES" ] && MIRROR_CANDIDATES="$DISK" \ || MIRROR_CANDIDATES="$MIRROR_CANDIDATES $DISK" fi done } mirrorBootDisk() { if [ -z "$MIRROR_CANDIDATES" ] ; then echo "\nNo suitable disks found for boot disk mirroring. The script will exit.\n" exit 1 fi echo "\nYou may mirror your boot disk with one of the following disks:" echo "(or press Ctrl-C to exit)\n" echo "$MIRROR_CANDIDATES\n" until [ "$VALID_CHOICE" -eq 1 ] do echo "Mirror disk? \c" read MIRROR_DISK [ -n "`echo $MIRROR_CANDIDATES | grep -w $MIRROR_DISK 2>/dev/null`" ] \ && VALID_CHOICE=1 done echo "\nMirroring ${BOOT_DISK} with ${MIRROR_DISK}...\n" # Duplicate the partition table on mirror disk prtvtoc /dev/rdsk/${BOOT_DISK}s2 | fmthard -s - /dev/rdsk/${MIRROR_DISK}s2 > /dev/null 2>&1 # Create state database replicas metadb -a -f -c2 /dev/dsk/${BOOT_DISK}s3 /dev/dsk/${MIRROR_DISK}s3 > /dev/null 2>&1 # Backup vfstab cp /etc/vfstab /etc/vfstab.pre_mirror # Backup /etc/system cp /etc/system /etc/system.pre_mirror # Mirror / (root) metainit -f d10 1 1 ${BOOT_DISK}s0 > /dev/null 2>&1 metainit -f d20 1 1 ${MIRROR_DISK}s0 > /dev/null 2>&1 metainit d30 -m d10 > /dev/null 2>&1 metaroot d30 > /dev/null 2>&1 # Mirror swap metainit -f d11 1 1 ${BOOT_DISK}s1 > /dev/null 2>&1 metainit -f d21 1 1 ${MIRROR_DISK}s1 > /dev/null 2>&1 metainit d31 -m d11 > /dev/null 2>&1 # Mirror /usr metainit -f d14 1 1 ${BOOT_DISK}s4 > /dev/null 2>&1 metainit -f d24 1 1 ${MIRROR_DISK}s4 > /dev/null 2>&1 metainit d34 -m d14 > /dev/null 2>&1 # Mirror /var metainit -f d15 1 1 ${BOOT_DISK}s5 > /dev/null 2>&1 metainit -f d25 1 1 ${MIRROR_DISK}s5 > /dev/null 2>&1 metainit d35 -m d15 > /dev/null 2>&1 # Mirror /files0 metainit -f d16 1 1 ${BOOT_DISK}s6 > /dev/null 2>&1 metainit -f d26 1 1 ${MIRROR_DISK}s6 > /dev/null 2>&1 metainit d36 -m d16 > /dev/null 2>&1 # Change the crash dump device to the DiskSuite swap metadevice dumpadm -d `swap -l | tail -1 | awk '{print $1}'` > /dev/null 2>&1 # Make the mirror disk bootable installboot /usr/platform/`uname -i`/lib/fs/ufs/bootblk /dev/rdsk/${MIRROR_DISK}s0 # Create a "mirror" device alias for the mirror disk MIRROR_DEVICE=`ls -l /dev/dsk/${MIRROR_DISK}s0 | awk -F- '{print $2}' | cut -c16- | sed 's/\/sd/\/disk/'` eeprom "nvramrc=devalias mirror $MIRROR_DEVICE" eeprom "use-nvramrc?=true" # Update vfstab cp /etc/vfstab /etc/vfstab.pre_mirror sed -e "s/\/dev\/dsk\/${BOOT_DISK}s1/\/dev\/md\/dsk\/d31/" \ -e "s/\/dev\/dsk\/${BOOT_DISK}s4/\/dev\/md\/dsk\/d34/" \ -e "s/\/dev\/rdsk\/${BOOT_DISK}s4/\/dev\/md\/rdsk\/d34/" \ -e "s/\/dev\/dsk\/${BOOT_DISK}s5/\/dev\/md\/dsk\/d35/" \ -e "s/\/dev\/rdsk\/${BOOT_DISK}s5/\/dev\/md\/rdsk\/d35/" \ -e "s/\/dev\/dsk\/${BOOT_DISK}s6/\/dev\/md\/dsk\/d36/" \ -e "s/\/dev\/rdsk\/${BOOT_DISK}s6/\/dev\/md\/rdsk\/d36/" \ /etc/vfstab > /etc/newvfstab mv /etc/newvfstab /etc/vfstab # Create /etc/rc2.d/S99attachmirrors cat << END_SCRIPT > /etc/rc2.d/S99attachmirrors metattach d30 d20 > /dev/null 2>&1 metattach d31 d21 > /dev/null 2>&1 metattach d34 d24 > /dev/null 2>&1 metattach d35 d25 > /dev/null 2>&1 metattach d36 d26 > /dev/null 2>&1 echo "\nBoot disk mirroring complete.\n" rm \$0 END_SCRIPT echo "To complete the mirroring, the system must be rebooted. Reboot now? (y/n) \c" read YN case $YN in [Yy]) echo "\nRebooting..." lockfs -fa init 6 exit ;; *) echo "\nPlease reboot the system at a later time to complete the mirroring.\n" exit ;; esac } # Main loop rootUserRequired checkDiskSuiteInstallation determineBootpath findMirrorCandidates mirrorBootDisk