Chinaunix首页 | 论坛 | 博客
  • 博客访问: 68242
  • 博文数量: 15
  • 博客积分: 681
  • 博客等级: 上士
  • 技术积分: 181
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-02 13:07
文章分类
文章存档

2011年(1)

2006年(1)

2005年(13)

我的朋友

分类:

2005-08-30 17:40:36

#! /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

阅读(1205) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~