#!/usr/local/bin/perl -w # Author: David Morris # Version: $Id: xp2dg,v 1.9 2004/11/05 21:03:10 davey Exp $ # Purpose: Turn LDEV's from XP disk array into a Veritas Diskgroup # License: Released under the GNU Public Licence (GPL) # The terms of the GPL are available at: # http://www.gnu.org/licenses/gpl.html use strict; use diagnostics; use Data::Dumper; use Getopt::Long; GetOptions( "host=s"=> \ (my $hostname) , "cbs=s" => \ (my $cbs), "help" => \ (my $help), "xp=s" => \ (my $xpfile), "disktype=s" => \ (my $disktype), "ctlr=s" => \ (my $ctlr), "<>" => sub {print "Error\n"}, ) or die Usage(); if (defined $help | ! defined @ARGV) { Usage(); exit; } # Set some sensible default values if ( ! defined $disktype) { $disktype = "OPEN-E"; } if ( ! defined $xpfile) { $xpfile = "xpout"; } if ( ! defined $cbs) { $cbs = "samp01"; } if ( ! defined $hostname) { $hostname = "testhost"; } sub Usage { print <<"EOF"; Usage: $0 --host=hostname --cbs=cbsname --disktype=type --ctlr=controller Examples: $0 --host=clyde-a --cbs=routpw01 --disktype=OPEN-E --ctlr=c4 --xp=xpout Notes: You will need a file with the output from "xpinfo -d," Bugs: - May not be able to pick up disks across controllers on HP-UX. To workaround it, you can use a regex for the controller name: --ctlr="c[8-9]" EOF } if ( -f "${cbs}.xp" ) { do "${cbs}.xp"; } else { die "Cannot find configuration file ${cbs}.xp in current directory"; } my $group; my $hashref; my $disk; my $dg; my @vxcommands; my $diskgroup; my %veritasgroups = ParseVeritasGroups($cbs); my @xparray = xp2array($xpfile); my @vxdisklist = vxdisk2array(); my @vxdiskmap; sub DgName { # Add the CBS (Call By Service) name to the standard # diskgroup names, oradata, archlogs, dataexec, etc. my $dg = shift; if ( $dg eq "apps" ) { # Handles the dg_apps_hostname type diskgroup my $diskgroup ='dg_'.${dg}.'_'.${hostname}; return $diskgroup; } else { # Handles dg_oradata_cbsnpw01 type diskgroups my $diskgroup ='dg_'.${dg}.'_'.${cbs}; return $diskgroup; } } sub PrintCommands { print @vxcommands; print "\n"; } sub xp2raw { # Map XP disk 01:1f to /dev/rdsk/c4t50060E8003EB6904d0s2 my $xpdisk = shift; my $xpline; foreach $xpline (@xparray) { if ( $xpline =~ /$xpdisk/ ) { my ($rawdevice, $s1, $s2, $s3, $xpdevice, $waste) = split /,/,$xpline; unless ($waste =~ /$disktype/ ) { next; } else { if ($rawdevice =~ $ctlr) { return $rawdevice; } } } } } sub xp2array { # This sub processes the contents of a comma delimited file # generated by the HP supplied "xpinfo" utility. To generate # this file: # xpinfo -d, > xpout # The contents look similar to: # #/dev/rdsk/c8t500060E8027F1302d0s2,1f4,00,CL1C,00:e1,OPEN-8,.... $xpfile = shift; open (XP,$xpfile) or die "Cannot open $xpfile"; my @xpout = ; close XP; return @xpout; } sub vxdisk2array { # Need to use vxdisk -e to get the raw device on Solaris. No -e flag on HP # so command is if ($^O eq "solaris") { open (VX,"vxdisk -e list |") or die "Cannot run vxdisk -e list"; my @vxdisklist = ; close VX; return @vxdisklist; } if ($^O eq "linux") { open (VX,"vxdisk-e.list") or die "Cannot open list file"; my @vxdisklist = ; close VX; return @vxdisklist; } if ($^O eq "hpux") { open (VX,"vxdisk list|") or die "Cannot open list file"; my @vxdisklist = ; close VX; return @vxdisklist; } } sub DiskFormat { # HP Disks need to be dd'ed to remove any LVM remnants. Sun Disks need to be formatted my $diskdevice = shift; if ($^O eq "solaris") { my $setupstring = "format -f format.txt $diskdevice" ; return "$setupstring"; } elsif ($^O eq "hpux") { my $setupstring = "dd if=/dev/zero of=$diskdevice bs=1024 count=1024"; return "$setupstring"; } elsif ($^O eq "linux") { my $setupstring = "format -f format.txt $diskdevice"; return "$setupstring"; } else { return "Don't know how to format disks on platform $^O"; } } sub vxdisksetup { } sub XPDiskVXDisk { my $disk = shift; foreach (@vxdisklist) { if ($_ =~ $disk) { my ($xpname, $rest) = split(/ /,$_); return $xpname; } } } sub DiskNamePrefix { # Return the first six characters of the diskgroup name # to use as the disk name. Turns dg_oradata_archpw01 into # dg_orad my $diskgroup = shift; my $diskprefix = substr($diskgroup, 0, 7); return $diskprefix; } foreach $dg (sort keys %veritasgroups) { my (@vxdiskmap, @formatcmds, @vxdisksetup, @vxdisks, @medianames); my $hashref = \%{$veritasgroups{$dg}}; my $numberofdisks = scalar(keys(%{$hashref})); my $diskgroup = DgName($dg); my $diskprefix = DiskNamePrefix($diskgroup); my $comment = "# Diskgroup: $diskgroup Number of disks: $numberofdisks\n"; print $comment; while (my ($key, $value) = each %$hashref) { my $xpdisk = ${$value}[0]; my $rawdevice = xp2raw($xpdisk); push @vxdiskmap, " # $key, $xpdisk, $rawdevice \n"; # raw device is /dev/rdsk/c?t0WWN.. so we need to split it to get C?t0WWN: my ($blank, $dev, $rdsk, $disk) = split(/\//, $rawdevice); my $vxdiskname = XPDiskVXDisk($disk); # my $diskformatstring = DiskFormat($rawdevice); push @formatcmds, " $diskformatstring\n"; push @vxdisksetup, " /etc/vx/bin/vxdisksetup -i $vxdiskname\n"; push @vxdisks, "$vxdiskname"; push @medianames, " vxedit -g $diskgroup rename $vxdiskname $diskprefix"."$key\n"; } print sort(@vxdiskmap); print "\n# Prepare disks so that Veritas can see them:\n"; print " echo -e \"l\\nq\" > format.txt\n"; print sort(@formatcmds); print "\n vxdctl enable\n\n"; print "# Setup disks for Veritas to use:\n"; print sort(@vxdisksetup); print "\n"; print "# Create Diskgroup: \n"; print " vxdg init $diskgroup "; print join(" ", @vxdisks); print "\n"; print "\n"; print "# Assign disk names:\n"; print sort(@medianames); print "\n\n"; } __END__ =head1 NAME: xp2dg --host=hostname --cbs=cbsname --disktype=type --ctlr=controller =head1 SYNOPSIS Turns a list of xp disks into a Veritas Diskgroup conforming to the Powergen Retail standard naming convention. =head1 DESCRIPTION Outputs commands needed to turn a list of LUN's from an HP XP storage array into a Veritas Diskgroup. Needs a file containing the output of: "xpinfo -d," =head2 OPTIONS: =over 4 =item --host the hostname where the diskgroups will be created, e.g. ward-0 =item --cbs call by service name, e.g. routpw01 =item --disktype - OPEN-E|OPEN-8 defaults to OPEN-E, =item --ctlr - a q =head2 EXAMPLE: xp2dg --host=clyde-a --cbs=routpw01 --disktype=OPEN-E --ctlr=c5 =cut