免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1765 | 回复: 0
打印 上一主题 下一主题

mirrors the root disk cleanly and safely! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-08-30 17:40 |只看该作者 |倒序浏览

#! /bin/sh
#
# mirrorRoot - mirrors the root disk cleanly and safely
#
################################################################
# Author: Todd Stansell
# $Id: mirrorRoot,v 1.21 2004-02-01 03:40:20-08 todd Exp $
#
# Notes:
#
#   1) I use vxprint -F ... throughout this script because of the
#      fact that vxprint -ht output is not consistent between versions.
#      Version 3.1 adds information about replication (since it's
#      now integrated).  Anyway, by pulling only the information
#      I need, I can be sure it will work without regard to version.
#
#   2) status codes of all veritas commands are documented in the
#      vxintro manpage.
#
#   3) versions previous to 1.18 don't deal with the Block0
#      subdisk correctly for VxVM 3.5.  So, make sure you're
#      using version 1.18 or newer.  You wouldn't see this
#      message if you weren't, though.
#
################################################################
#! /bin/sh
#
# mirrorRoot - mirrors the root disk cleanly and safely
#
################################################################
# Author: Todd Stansell
# $Id: mirrorRoot,v 1.21 2004-02-01 03:40:20-08 todd Exp $
#
# Notes:
#
#   1) I use vxprint -F ... throughout this script because of the
#      fact that vxprint -ht output is not consistent between versions.
#      Version 3.1 adds information about replication (since it's
#      now integrated).  Anyway, by pulling only the information
#      I need, I can be sure it will work without regard to version.
#
#   2) status codes of all veritas commands are documented in the
#      vxintro manpage.
#
#   3) versions previous to 1.18 don't deal with the Block0
#      subdisk correctly for VxVM 3.5.  So, make sure you're
#      using version 1.18 or newer.  You wouldn't see this
#      message if you weren't, though.
#
################################################################
mirror_dev="c0t1d0"
mirror_name="rootdisk2"
verbose=0
c_opt=false
setswaponly=false
PATH=$PATH:/usr/sbin:/etc/vx/bin
PROG=`basename $0`
USAGE="usage: $PROG [-hvc] [ [-s] | [-n name] [-d device] ]
        -h   help
        -s   create swap slices and configure dump device only
        -v   increase verbosity level (two -v's for max)
        -c   show vx commands as they are run
   
-n name   disk access name of mirror disk (default is $mirror_name)

-d device   device used to mirror onto (default is $mirror_dev)"
#
# kills off any processes that are running in the background
#
cleanup() {
   
vxtask abort $PROG
}
#
# echo a message if we want vx command verbosity
#
show() { [ $c_opt ] && /bin/echo "# $@" ; }
#
# echo a message if we want verbosity
#
msg() { [ $verbose -ge 1 ] && /bin/echo "$@" ; }
#
# usage: showstatus $value $prog $msg
#
showstatus() {
    status="$1"
    prog="$2"
   
if [ $status -ne 0 ] ; then
       
echo "$3" >&2
       
echo "  $prog exited with status $status" >&2
       
exit $status
   
fi
}
#
# Check to see that $device has at least $size sectors
# usage: check_size $device $size
#
check_size() {
  
  len=`vxprint -e 'sd && sd_disk="'$dm_of_rootvol'" && p0 = "PRIVATE"' -F "%len" | awk '{a=a+$1}END{print '$2'-a}'`
   
pub_len=`vxdisk list $1 | awk -F= '/^public:/ {print $NF}'`
   
if [ $pub_len -lt $len ] ; then
       
echo "$mirror_dev is only $pub_len sectors, while" >&2
       
echo "$dm_of_rootvol uses $len sectors.  Please choose a larger disk." >&2
       
exit 7
   
fi
}
#
# usage: initdisk $device
#
initdisk() {
   
dev=$1
   
# see if we need the old_layout option to vxdisksetup.  This
   
# is required if we have a fully-utilized disk that has been
   
# encapsulated, so that only 1 cylinder is used for the private
   
# region, and the new disk will have enough public space to
   
# mirror everything to.  If you don't want it to use this option,
   
# then initialize the disk before running this script.
   
opt=""
   
if grep old_layout /etc/vx/bin/vxdisksetup >/dev/null ; then
       
opt="old_layout"
   
fi
   
msg "Initializing $dev for use with volume manager"
   
show "vxdisksetup -i $dev $opt"
   
vxdisksetup -i $dev $opt; status=$?
   
showstatus $status vxdisksetup "Could not initialize $dev"
}
#
# adds a device ($dev) to a disk group ($dg) with specified media name ($dm)
#
# usage: add_to_dg $dev $dm [$dg]
#
add_to_dg() {
   
dg=rootdg
   
dev=$1
   
dm=$2
   
[ "$3" ] && dg=$3
   
msg "Adding $dev to $dg as $dm"
   
show "vxdg -g $dg adddisk $dm=$dev"
   
vxdg -g $dg adddisk $dm=$dev; status=$?
   
showstatus $status vxdg "Could not add $dev to $dg as "$dm""
}
#
# Display the running tasks with the current date
#
# usage: showtasks
#
showtasks() {
   
echo ============= `date` =============
   
vxtask -l list $PROG | egrep "Operation|Work|Progress|^$"
}
#
# simply waits for all tasks with our taskid ($PROG) have finished
#
# usage: taskwait
#
taskwait() {
   
out=`vxtask list $PROG 2>&1`
   
status=$?
   
i=0; o=`echo "$out" | wc -l`
   
[ $status -eq 0 -a $verbose -ge 2 ] && showtasks
   
while [ $status -eq 0 ] ; do
       
if [ $verbose -ge 2 ] ; then
          
u=`echo "$out" | wc -l`
            
if [ $u -ne $o ] ; then
               
showtasks
               
o=$u
            
fi
            
j=`expr $i % 4`
            
case $j in
               
0)        /bin/echo '|c' ;;
               
1)        /bin/echo '/c' ;;
               
2)        /bin/echo '-c' ;;
               
3)        /bin/echo '\c' ;;
            
esac
            
i=`expr $i + 1`
       
fi
        
sleep 2
        
out=`vxtask list $PROG 2>&1`
        
status=$?
   
done
}
#
# usage: mirrorto $dmname
#
mirrorto() {
   
dm=$1
   
#
   
# We start by mirroring rootvol, since it's special
   
#
   
msg "Starting mirror of rootvol to $dm..."
   
show "vxrootmir -t $PROG $dm"
   
vxrootmir -t $PROG $dm ; status=$?
   
showstatus $status vxrootmir "Could not mirror rootvol to $dm"
   
#
   
# Now mirror the rest of the volumes.
   
#
   
for vol in $vols_on_dm ; do
       
if [ $vol = "rootvol" ] ; then
               
continue
       
fi
       
msg "Starting mirror of $vol onto $dm..."
       
show "vxassist -b -g rootdg -t $PROG mirror $vol $dm"
       
vxassist -b -g rootdg -t $PROG mirror $vol $dm; status=$?
       
showstatus $status vxassist "Mirror of $vol onto $dm FAILED"
   
done
   
taskwait
}
#
# make sure swap has a valid partition entry so
# we can use it as a dump device, and also set
# dumpadm to use that new slice.
#
setSwap() {
   
swap=`vxprint -g rootdg -e 'sd && assoc.assoc.v_use_type="swap"' -F '%name'`
   
if [ -n "swap" ] ; then
          
msg "Making sure $swap has valid partition entries."
            
slice=""
            
for sd in $swap ; do
               
    # vxmksdpart -g rootdg   
                  
show "vxmksdpart -g rootdg $sd 1 0x03 0x01"
                    
if [ -z "$slice" ] ; then
                       
slice="`vxprint -g rootdg -F '%device_tag' $sd`s1"
                    
fi
            
done
            
if [ -f /etc/dumpadm.conf ] ; then
               
if [ -n "$slice" ] ; then
                  
msg "Configuring dumpadm for swap slice $slice"
                    
show "dumpadm -d /dev/dsk/$slice"
               
else
                  
echo "Could not determine slice to use for dump device!" >&2
               
fi
            
fi
   
fi
}
#############################################
#         BEGIN MAIN PROGRAM
#############################################
#
# lets try to clean things up if we die
#
trap cleanup 1 2 3 5 15
while getopts vcsn:d:h c; do
       
case $c in
       
v)        verbose=`expr $verbose + 1`
       
        ;;
       
c)        c_opt="true"
       
        ;;
       
n)        mirror_name=$OPTARG
       
        ;;
       
d)        mirror_dev=$OPTARG
       
        ;;
       
s)        setswaponly=true
       
        ;;
       
*)        echo "$USAGE" >&2
       
        exit 64
       
        ;;
       
esac
done
shift `expr $OPTIND - 1`
#########
# Make sure a bunch of stuff is ok before we begin
#########
# make sure we're root
if /bin/id | grep -v '^uid=0(' >/dev/null ; then
        echo "$PROG: must be run as root" >&2
        exit 64
fi
# make sure vxvm is installed
if pkginfo VRTSvxvm >/dev/null 2>&1 ; then
        version=`pkginfo -x VRTSvxvm | tail -1 | sed 's/.*) (.).*/1/'`
else
        echo "$PROG: VRTSvxvm not installed" >&2
        exit 64
fi
# make sure vxvm is 3.x or greater
if [ -z "$version" -o $version -lt 3 ] ; then
        echo "$PROG: This script requires VRTSvxvm 3.x or greater to function." >&2
        exit 64
fi
# make sure we're encapsulated
vxprint -g rootdg rootvol >/dev/null
if [ $? -ne 0 ] ; then
        echo "$PROG: rootvol doesn't exist.  This probably means" >&2
        echo "your root disk is not encapsulated yet." >&2
        exit 64
fi
if $setswaponly ; then
        setSwap
        exit
fi
#########
# Now we should be ready to go...
#########
#
# Find out where we're mirroring from, and what that includes.
#
dm_of_rootvol=`vxprint -r -g rootdg -F "%rtype %name" rootvol |
                awk '/^dm/{print $NF; exit}'`
dev_of_rootvol=`vxprint -g rootdg -F "%device_tag" $dm_of_rootvol`
msg "using $dm_of_rootvol to determine volumes to mirror..."
sds_on_dm=`vxprint -g rootdg
                -e 'sd_disk = "'$dm_of_rootvol'"'
                -F "%name" | sort`
plexs_on_dm=`vxprint -g rootdg
       
        -e 'pl_subdisk.sd_disk = "'$dm_of_rootvol'"'
       
        -F "%name" | sort`
vols_on_dm=`vxprint -g rootdg
                -e 'v_plex.pl_subdisk.sd_disk = "'$dm_of_rootvol'"'
                -F "%name" | sort`
msg "  volumes to be mirrored: "$vols_on_dm
size_of_dm=`vxprint -F "%len" $sds_on_dm | awk '{a=a+$1}END{print a}'`
msg "  total space required: $size_of_dm sectors"
#
# Check if $mirror_dev is being used already.
#
msg "Checking "$mirror_dev" for use as destination mirror..."
for dg in `vxdg -q list | grep -v rootdg | awk '{print $1}'` ; do
        dev=`vxprint -d -g $dg -F "%name %device_tag" |
                awk '$NF=="'$mirror_dev'" {print $1}'`
        if [ ! -z "$dev" ] ; then
                echo "$mirror_dev is used in the $dg disk group as $dev" >&2
                exit 5
        fi
done
#
# We check to see if $mirror_dev is part of rootdg
#
dm_mirror=`vxprint -d -g rootdg -F "%name %device_tag" |
        awk '$NF=="'$mirror_dev'" {print $1}'`
if [ -n "$dm_mirror" ] ; then
        #
        # $mirror_dev is already part of rootdg, now see if it's being used
        #
        sd_num=`vxprint -F "%sd_num" $dm_mirror`
        if [ $sd_num -gt 0 ] ; then
            echo "$dm_mirror ($mirror_dev) already belongs to rootdg and" >&2
            echo "contains $sd_num subdisks.  Please choose a different" >&2
            echo "device to use or clean out $mirror_dev" >&2
            exit 6
        fi
        #
        # verify space requirements
        #
        check_size $mirror_dev $size_of_dm
else
        #
        # the device ($mirror_dev) is not part of a disk group.  Now we
        # check if it is currently initialized.  If not, we initialize it.
        # Then, we make sure it's part of rootdg.
        #
        dm_mirror=$mirror_name
        show "vxdisk list $mirror_dev"
        vxdisk list $mirror_dev | grep "^private:" >/dev/null; status=$?
        if [ $status -eq 0 ] ; then
                #
                # the disk is initialized already
                #
                msg "$mirror_dev is already initialized and unallocated."
        else
                initdisk $mirror_dev
        fi
        #
        # verify device is large enough
        #
        check_size $mirror_dev $size_of_dm
        #
        # now add the disk to rootdg
        #
        add_to_dg $mirror_dev $dm_mirror rootdg
fi
#
# At this point, we have an initialized, clean disk in rootdg
# named $dm_mirror that is large enough to hold all of the volumes.
#
mirrorto $dm_mirror
#
# Now we need to check if the original disk was an encapsulated
# one, or if it was already converted to an initialized one.
#
priv=`vxprint -e 'sd &&
                  sd_disk="'$dm_of_rootvol'" &&
                  putil0!=""'
              -F "%name"`
# $priv should now be something like "rootdiskPriv" or "rootdisk1Priv"
if [ -n "$priv" ] && echo $sds_on_dm | grep "$priv" >/dev/null ; then
        msg "$dm_of_rootvol appears to be encapsulated, continuing..."
else
        msg "$dm_of_rootvol does not appear to be encapsulated.  We're done."
        exit 0
fi
msg "Removing all mirrors that use $dm_of_rootvol..."
for vol in $vols_on_dm ; do
        msg "  removing from $vol...c"
        show "vxassist -g rootdg remove mirror $vol !$dm_of_rootvol"
        vxassist -g rootdg remove mirror $vol !$dm_of_rootvol; status=$?
        if [ $status -ne 0 ] ; then
                msg "FAILED"
        fi
        showstatus $status vxassist "Failed to remove mirror of $vol"
        msg "ok"
done
#
# remove the encapsulation private subdisk (typically, rootdiskPriv)
#
if [ -z "$priv" ] ; then
        echo "No private subdisk found?  This isn't normally the case."
else
        if vxprint -e 'sd && sd_name="'%priv'"' >/dev/null ; then
                show "vxedit -g rootdg rm $priv"
                vxedit -g rootdg rm $priv
                status=$?
                showstatus $status vxedit "Failed to remove $priv subdisk from rootdg"
        fi
fi
#
# remove disk from rootdg
#
msg "Removing $dm_of_rootvol from rootdg..."
show "vxdg -g rootdg rmdisk $dm_of_rootvol"
vxdg -g rootdg rmdisk $dm_of_rootvol; status=$?
showstatus $status vxdg "Failed to remove $dm_of_rootvol from rootdg"
#
# re-initialize the disk
#
initdisk $dev_of_rootvol
#
# add the disk to rootdg
#
add_to_dg $dev_of_rootvol $dm_of_rootvol rootdg
#
# mirroring volumes.
#
mirrorto $dm_of_rootvol
setSwap

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/4019/showart_45274.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP