Article Figure 1 Listing 1 Listing 2 Listing 3
Listing 4 feb2007.tar

Listing 2 Detach_attach_mirrors

#!/bin/bash
##################################################
#  
# detach__attach_mirrors.sh:
#   This script checks to see which metadevices
#   are actually mounted by /etc/vfstab. 
#
#   The script is concerned with attaching the 
#   or detaching the mirrors for the /, /var, /usr, 
#   and swap partitions. Other mirrors are not 
#   touched by this script. 
#  
#   If one of the system filesystems is running
#   under a mirror, the script makes sure the 
#   mirror has "Okay" status, before attempting 
#   to metattach the secondary mirror. Or, if 
#   detaching, the submirrors are checked to make
#   sure that each has a status of "Okay" before
#   the metadetach command is called to break the
#   mirror.
#
#
# Author: James Hartley
# Version:2 
# Date: 09/12/2006
#
# Usage: 
#
#./detach_attach_mirrors.sh [attach|detach|cleanup]
#
# Special Instructions:
#
# This script uses four special files that it 
# creates when the script is run. These files are
# 
# $TMPDIR/$TMPVFTAB_ORG  -- original  vfstab file
# $TMPDIR/$TMPMETA_ORG   -- original  metastat output
# $TMPDIR/$TMPVFTAB_AFTER --vfstab after breaking mirror
# $TMPDIR/$TMPMETA_AFTER -- metastat after breaking mirror
#
# These files are managed by the script and should 
# not be edited by the users of the system. Although
# the script can be run as a standalone script to 
# break and reconstruct mirrors. the script is 
# designed to be run via the cron facility and as 
# such the order in which the scripts should be run 
# is:  
# 
# ./detach_attach_mirrors.sh detach
# ./detach_attach_mirrors.sh attach
# ./detach_attach_mirrors.sh clean
# 
# This order preserves the integrity of the temporary 
# files during patching. 
# 
# CAUTION -- attaching requires the use of the old 
# metastat data to reattach the corresponding 
# submirrors to the correct mirror. It is essential
# that the old information be stored in a file for 
# this purpose. DO NOT DELETE the file
#
# $/TMPDIR/$TMPMETA_ORG
# 
# This file contains the old metadata required to 
# attach teh submirrors after the mirrors have been 
# broken. 
# 
# If this file is missing you will be forced to 
# reconstruct the mirrors by hand. 
# 
##################################################
#  DEBUG LINE
set -x
#   
PATH=/usr/sbin:/usr/bin
export PATH


TMPDIR="/var/tmp"
TMPVFTAB_ORG="vfsout_before_breaking"
TMPMETA_ORG="metaout_before_breaking"
TMPVFTAB_AFTER="vfsout_after_breaking"
TMPMETA_AFTER="metaout_after_breaking"

LOGFILE="/etc/patchlog"
PATCHFLAG="/etc/patchflag"
HOST=`/usr/bin/hostname`
FROM="unixdude@ymp.gov"
SUBJECT="breaking mirror from $HOST"
RECIPIENT="root"
continue="false"

mailmessage ()
{
   echo $1 | mailx -r $FROM -s "$SUBJECT" $RECIPIENT
}


function usage() 
{ 
  echo "Usage $0 [attach | detach | clean]"
}

function deattachit ()  
{
  mirror=`grep ^$1 $TMPDIR/$TMPMETA_ORG`
  f1=`echo $mirror | awk '{print $1}'`
  f2=`echo $mirror | awk '{print $2}'`
  f3=`echo $mirror | awk '{print $3}'`
  f4=`echo $mirror | awk '{print $4}'` 
  echo "$f1 $f2 $f3 $f4"
  if [ $f2 = "Okay" -a $f3 = "Okay" ]; then
#       echo "detach $f1 $f4"
      metadetach $f1 $f4
      if [ $? -ne 0 ]; then
         return 1
       else
         return 0
      fi
  else
        return 1
  fi
}

function attachit ()  
{
  mirror=`grep ^$1 $TMPDIR/$TMPMETA_AFTER`
  f1=`echo $mirror | awk '{print $1}'`
  f2=`echo $mirror | awk '{print $2}'`
  submirror=`grep ^$1 $TMPDIR/$TMPMETA_ORG`
  f4=`echo $submirror | awk '{print $4}'`
  echo "$f1 $f2 submirror $f4"
  if [ $f2 = "Okay" ]; then
#       echo "attach $f1 $f4"
      metattach $f1 $f4
      if [ $? -ne 0 ]; then
         return 1
      else
         return 0
      fi
  else
       return 1
  fi
}

function cleanup ()
{
#
#  cleanup the TMPDIR 
#

if [ -f $TMPDIR/$TMPVFTAB_ORG ]; then 
    rm $TMPDIR/$TMPVFTAB_ORG
fi
if [ -f $TMPDIR/$TMPMETA_ORG ]; then 
    rm $TMPDIR/$TMPMETA_ORG
fi
if [ -f $TMPDIR/$TMPVFTAB_AFTER ]; then 
    rm $TMPDIR/$TMPVFTAB_AFTER
fi
if [ -f $TMPDIR/$TMPMETA_AFTER ]; then 
    rm $TMPDIR/$TMPMETA_AFTER
fi
  
}
##################################
#
#  Start Main Code
#
##################################

##################################
#
# Check the arguments
#
# for -p patching calls the detach so
# $LOGFILE and $PATCHFLAG must exist
# and the argument DETACH is the only
# valid argument for detach_attach_mirrors
# logging is assumed and errors are directed
# to the $LOGFILE.
#
# if ! -p then detach attach is called
# interactively
#
##################################

if [ ! -z $1 ]; then
if [ $1 = -p ]; then
   if [ -f $PATCHFLAG -a -f $LOGFILE ]; then
        continue=true
   fi
   if [ $continue != "true" ]; then
      exit 1
   fi
   shift
fi
fi
ATTACH=$1

if [ -z $ATTACH ]; then
    if [ $continue == "true" ]; then
       echo "detach with -p option has no argument detach failed on \
         $HOST" >> $LOGFILE
       echo "patch failed: no argument to detach_attach script"  >> $LOGFILE
       echo "moving $LOGFILE and $PATCHFLAG to halt patch process" >> $LOGFILE
       mailmessage "detach with -p option has no argument patch failed on $HOST"
       mv $LOGFILE $LOGFILE.`date +%y%m%d`
       rm $PATCHFLAG
       exit 1
    else
       usage
       exit 1
    fi
else
   if [ $continue == "true" ] && [ $ATTACH != "detach" ]; then
      echo "detach failed due to $ATTACH option on $HOST" >> $LOGFILE
      echo "only detach option is allowed for patching" >> $LOGFILE
      mailmessage "patch failed: $ATTACH option on $HOST not \
        allowed during patch"
      mv $LOGFILE $LOGFILE.`date +%y%m%d`
      rm $PATCHFLAG
      exit 1
   fi
fi


NODEVICES=`metastat 3>&2 2>&1 1>&3  | sed '$d' | awk '{print $5, $6, $7}'`
if [ "${NODEVICES}" = "no existing databases" ]; then
     echo "no metadevices to break/attach on $HOST"
     if [ $continue = "true" ]; then
        echo "no metadevices to break/attach on $HOST" >> $LOGFILE
     fi
     mailmessage "no metadevices to break/attach on $HOST"
     exit 0
fi

if [ $ATTACH = "detach" ]; then 

   metastat | awk 'BEGIN{RS=""; FS="\n"; ORS="\n\n"}{print \
     $1,$2,$3,$4,$5,$6}' | sed 's/^ //' | grep ': Mirror' | sed 's/://' \
     | awk '{print $1,$7,$12,$10}' | sort > $TMPDIR/$TMPMETA_ORG
   cat /etc/vfstab | grep '^/dev/md' | sed 's#/dev/md/dsk/##' \
     | awk '{print $1,$3}' | sed 's/-/swap/' | sort > $TMPDIR/$TMPVFTAB_ORG

   for i in / swap /var /usr
   do
     value=`grep "$i$" $TMPDIR/$TMPVFTAB_ORG | awk '{print $1}'`
     if [ ! -z "$value" ]; then
        deattachit "$value"
         if [ $? -ne 0 ]; then
            if [ $continue = "true" ]; then
                echo "ERROR detaching $value on $HOST" >> $LOGFILE
        mv $LOGFILE $LOGFILE.`date +%y%m%d`
        rm $PATCHFLAG
            fi
            mailmessage "ERROR detaching $value on $HOST"
            exit 1
         fi
     fi 
   done
   if [ $continue = "true" ]; then
        echo "Success detaching on $HOST" >> $LOGFILE
   fi
   mailmessage "Success detaching on $HOST"
   exit 0

elif [ $ATTACH = "attach" ]; then
   
   if [ ! -f $TMPDIR/$TMPMETA_ORG ]; then
         echo "opps some dummy erased the old meta file"
         echo "you will have to recreate the mirror by hand now" 
         echo "GOOD LUCK"
     echo "P.S. it would be good to run the script with 'clean'"
         echo "as an argument to get rid of any tmp files"
         exit 1
   fi
   metastat | awk 'BEGIN{RS=""; FS="\n"; \
     ORS="\n\n"}{print $1,$2,$3,$4,$5,$6}' | sed 's/^ //' \
     | grep ': Mirror' | sed 's/://' | awk '{print $1,$7}'\
     | sort > $TMPDIR/$TMPMETA_AFTER
   cat /etc/vfstab | grep '^/dev/md' | sed 's#/dev/md/dsk/##' \
     | awk '{print $1,$3}' | sed 's/-/swap/' | sort > $TMPDIR/$TMPVFTAB_AFTER

   for i in / swap /var /usr
   do
     value=`grep "$i$" $TMPDIR/$TMPVFTAB_ORG | awk '{print $1}'`
     if [ ! -z "$value" ]; then
        attachit "$value"
        if [ $? -ne 0 ]; then
           mailmessage "ERROR attaching $value on $HOST"
           exit 1
        fi
     fi 
   done
   mailmessage "Success attaching on $HOST"
   exit 0

elif [ $ATTACH = "clean" ]; then  
   echo "clean up tmp directory" 
   cleanup
   exit 0 
else 
   usage
   exit 1
fi