#!/usr/bin/ksh93
################################################################
function usagemsg_mapluns {
print "
Program: mapluns.sh
The purpose of this script is to map the disks from a
VIO server to their respective virtual SCSI slot
numbers, virtual adapters, and LDEV numbers.
This script is intended to be run on a VIO server in the
"oem_setup_env" environment. The output from this script
is a table of information containing the name of the VIO
server, hdisk name, virtual adapter name, virtual slot
number, the SAN LDEV ID, VTD, and associated partitions.
Usage: ${1##*/} [-?vV] [-h HMCname -u HMCuser]
[-n #] [-s SystemName1,...]
Where:
-v = Verbose mode - displays lsvioslot function info
-V = Very Verbose Mode - debug output displayed
-h = HMC machine name
-u = HMC user name
-n # = Prompt the user # times to select managed systems
-s = List of managed system names from which to obtain slot information
Author: Dana French (dfrench@mtxia.com)
Copyright 2006, All Rights Reserved
\"AutoContent\" enabled
"
}
################################################################
####
#### Description
####
#### Assumptions:
####
#### Dependencies:
####
#### Products:
####
#### Configured Usage:
####
#### Details:
################################################################
function mapluns {
typeset VERSION="2.0"
typeset TRUE="1"
typeset FALSE="0"
typeset EXITCODE="0"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset HMCLIST="${FALSE}"
typeset USEMAP="${FALSE}"
typeset USEMAPFILE=""
typeset HMCUSER=""
typeset HMCNAME=""
typeset LPARNAME=""
typeset SYSNAMES=""
typeset SYSNAME=""
typeset SYSNBR="0"
typeset HDISK=""
typeset VHOST=""
typeset VSLOT=""
typeset LDEV=""
typeset TMPDISK=""
typeset LSCFG=""
typeset LINE=""
typeset ICNT="0"
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
while getopts ":vVu:h:s:n#" OPTION
do
case "${OPTION}" in
'u') HMCUSER="${OPTARG}";;
'h') HMCNAME="${OPTARG}";;
's') IFS=$' \t,:/'
SYSNAMES=( ${OPTARG} )
SYSNBR="${#SYSNAMES[*]}"
IFS=$' \t\n';;
'n') SYSNBR="${OPTARG}";;
'L') USEMAP="${TRUE}"
USEMAPFILE="${OPTARG}";;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
[?:#]) usagemsg_mapluns "${0}" && return 1 ;;
esac
done
shift $(( ${OPTIND} - 1 ))
trap "usagemsg_mapluns ${0}" EXIT
if (( USEMAP == TRUE )) && [[ ! -s "${USEMAPFILE}" ]]
then
usagemsg_mapluns "Invalid LUN map file name"
return 1
fi
trap "-" EXIT
unset VFLAG
(( VERYVERB == TRUE )) && set -x
(( VERBOSE == TRUE )) && typeset VFLAG="-v"
(( VERBOSE == TRUE )) && print -u 2 -- "# Program: ${0}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Version: ${VERSION}"
################################################################
#### Retrieve Slot numbers from the multiple frames.
####
if [[ "_${HMCNAME}" != "_" ]] && [[ "_${HMCUSER}" != "_" ]]
then
typeset -A LNAMES
typeset -A NODISKS
for (( IDX=0; IDX /tmp/tmp${$}.sh
# . /tmp/tmp${$}.sh
# rm -f /tmp/tmp${$}.sh
eval $( lsvioslot -h ${HMCNAME} -u ${HMCUSER} -s ${SYSNAME} ${VFLAG} )
for NAME in "${!LPAR_NAME[@]}"
do
if [[ "_${LPAR_NAME[${NAME}]}" == "_aixlinux" ]]
then
LNAMES[${NAME}]="${LPAR_NAME[${NAME}]}"
NODISKS[${NAME}]="${LPAR_NAME[${NAME}]}"
# print "LNAMES[${NAME}]=${LNAMES[${NAME}]}"
fi
done
done
fi
unset LPAR_NAME
################################################################
####
#### Retrieve a list of VHOST adapters and their
#### associated SLOT numbers from the localhost VIO server.
####
lscfg -l 'vhost*' |
while read -r -- VHOST SLOT JUNK
do
ALLSLOTS[${SLOT##*-C}]="${VHOST}"
done
################################################################
#### Retrieve a list of all disks and LUN ID numbers.
typeset -A ALLDISKS
lscfg -vl 'hdisk*' |
egrep 'hdisk|Z1' |
while IFS=$' \t\n' read -r -- HDISK JUNK
do
IFS=')' read -r -- F1 LDEV
LDEV="${LDEV//./}"
LDEV="${LDEV%% *}"
ALLDISKS[${HDISK}]="${LDEV}"
done
IFS=$' \t\n'
typeset -A PVIDS
lspv | while IFS=$' \t\n' read -r -- HDISK PVID JUNK
do
PVIDS[${HDISK}]="${PVID}"
done
IFS=$' \t\n'
#### Retrieve a list of all VHOST information from the
#### localhost VIO server.
IFS=$'\n'
LSMAP=( $( /usr/ios/cli/ioscli lsmap -all ) )
typeset HOSTID=$( hostname )
print -u 2 "# hostname:hdisk:vadapter:vslot:ldev:pvid:vtd:lpars"
#### Parse though the stored VHOST information, one line at a
#### time, extracting specfic pieces of information.
for MAPLN in "${LSMAP[@]//Backing device/BackingDevice}"
do
#### Determine if the line of VHOST information contains the
#### VHOST ID, backing device name, or VTD name. If not,
#### continue with the next iteration of the loop.
[[ "_${MAPLN}" != _@(vhost|BackingDevice|VTD)* ]] && continue
#### If the line of VHOST information contains the VHOST ID,
#### extract the VHOST ID, and the SLOT number from this
#### line and continue with the next iteration of the loop.
if [[ "_${MAPLN}" = _vhost* ]]
then
VHOST=${MAPLN%%[$' \t']*}
VHOST=${VHOST#*[$' \t']}
VSLOT=${MAPLN##*-}
VSLOT=${VSLOT%%[$' \t']*}
continue
fi
#### If the line of VHOST information contains the VTD,
#### extract the VTD from this line and continue with
#### the next iteration of the loop.
if [[ "_${MAPLN}" = _VTD* ]]
then
VTD=${MAPLN##*[$' \t']}
[[ "_${VTD}" == _FOUND ]] && VTD=""
continue
fi
HDISK=${MAPLN##*[$' \t']}
TMPDISK="${HDISK}"
#### Identify an hdisk associated with the HDLM disk
#### device.
if [[ "_${TMPDISK}" = _dlmfdrv* ]]
then
TMPDISK=$( /usr/DynamicLinkManager/bin/dlnkmgr view -drv |
grep "${TMPDISK}" |
awk '{ print $3 }' |
head -1 )
fi
#### Obtain the hdisk configuration settings from the
#### ODM and store in an array.
LSCFG=( $( lscfg -vl ${TMPDISK} ) )
#### Loop through the array and extract the LDEV number.
for LINE in "${LSCFG[@]}"
do
if [[ "_${LINE}" = *\(Z1\)* ]]
then
LDEV=${LINE#*\(Z1\)}
LDEV=${LDEV//./}
LDEV=${LDEV%%[$' \t']*}
fi
done
####
#### Read through a previously created DISKMAP file and
#### extract the LABEL information from the last field
####
typeset LABEL=""
if (( USEMAP == TRUE )) && [[ -s "${USEMAPFILE}" ]]
then
while IFS=":" read -r -A -- PREV
do
[[ "_${PREV[4]}" == "_${LDEV}" ]] &&
LABEL="${PREV[5]//$'\t'/} ${PREV[6]//$'\t'/}"
done < "${USEMAPFILE}"
fi
typeset LPARNAME=""
typeset LNAME
for LNAME in "${!LNAMES[@]}"
do
unset ARY
typeset ARY
typeset IDX
eval ARY="( \${!SLOT_${LNAME}[@]} )"
for IDX in "${ARY[@]}"
do
# print "SLOT_${LNAME}[${IDX}]"
if (( ${IDX} == ${VSLOT//[!0-9]/} ))
then
LPARNAME="${LPARNAME},${LNAME}"
unset NODISKS[${LNAME}]
unset ALLSLOTS[${IDX}]
fi
done
done
LPARNAME="${LPARNAME#,}"
PVID="${PVIDS[${HDISK}]}"
print -u 2 "# ${HOSTID}:${HDISK}:${VHOST}:${VSLOT}:${LDEV}:${PVID}:${VTD}:${LPARNAME}:\t${LABEL}"
DISK_ARY[ICNT]="${HDISK}"
CMD_ARY[ICNT++]="/usr/ios/cli/ioscli mkvdev -vdev ${HDISK} -vadapter ${VHOST} -dev ${VTD}"
# HDISK="" VHOST="" VSLOT="" LDEV=""
HDISK="" LDEV="" VTD=""
done
#### List of HDISKs not associated with any virtual LPAR
print -u 2 "# \n# List of HDISKs not associated with any virtual LPAR"
print -u 2 "# hostname:hdisk:vadapter:vslot:ldev:pvid:vtd:lpars"
HDISK="" VHOST="" VSLOT="" LDEV="" VTD="" LPARNAME="" PVID=""
# ALLDISKS=( $( lsdev -Cc disk -F name ) )
for HDISK in "${!ALLDISKS[@]}"
do
IFS=":"
if [[ "_${DISK_ARY[*]}" != *${HDISK}*(:*) ]]
then
LDEV="${ALLDISKS[${HDISK}]}"
PVID="${PVIDS[${HDISK}]}"
print -u 2 "# ${HOSTID}:${HDISK}:${VHOST}:${VSLOT}:${LDEV}:${PVID}:${VTD}:${LPARNAME}"
fi
done
LDEV=""
PVID=""
#### List of LPAR's not associated with any virtual scsi adapters
print -u 2 "# \n# List of LPAR's not associated with any virtual SCSI adapters"
print -u 2 "# hostname:hdisk:vadapter:vslot:ldev:pvid:vtd:lpars"
HDISK=""
for LNAME in "${!NODISKS[@]}"
do
print -u 2 "# ${HOSTID}:${HDISK}:${VHOST}:${VSLOT}:${LDEV}:${PVID}:${VTD}:${LNAME}"
done
#### List of virtual SCSI adapters and slots not associated with any LPAR
print -u 2 "# \n# List of virtual SCSI adapters and slots not associated with any LPAR"
print -u 2 "# hostname:hdisk:vadapter:vslot:ldev:pvid:vtd:lpars"
unset LNAME
for VSLOT in "${!ALLSLOTS[@]}"
do
VHOST="${ALLSLOTS[${VSLOT}]}"
print -u 2 "# ${HOSTID}:${HDISK}:${VHOST}:C${VSLOT}:${LDEV}:${PVID}:${VTD}:${LNAME}"
done
print
#### Print the VIO command lines required to recreate the current
#### VHOST adapter configuration.
for LINE in "${CMD_ARY[@]}"
do
print "${LINE}"
done
return 0
}
################################################################
################################################################
function usagemsg_lsvioslot {
print "
Program: lsvioslot
List the slot adapters and associated slot numbers for one
or more LPAR's from a VIO server.
Usage: ${1##*/} [-?vV] -h HMCname [-l LPARname] [-u HMCuser]
[-s SystemName] [-L] [-d] [-k] [-D X]
Where:
-v = Verbose mode - displays lsvioslot function info
-V = Very Verbose Mode - debug output displayed
-h = HMC machine name
-u = HMC user name
-l = List slots/slots for specific LPAR
-s = System name from which to obtain slot information
-L = Display a list of systems managed by the specified HMC
-d = Output is formatted as colon (:) delimited data records
-k = Output is coded as Korn Shell 93 arrays (Default)
-D X = Specify a different delimiter to use in delimited data records
Author: Dana French (dfrench@mtxia.com)
Copyright 2006, All Rights Reserved
\"AutoContent\" enabled
"
}
################################################################
####
#### Description:
####
#### The lsvioslot function retrieves "slot" information for
#### virtual SCSI adapters from an HMC and builds formatted
#### output based upon user requirements. The formatted
#### output can take the form of Korn Shell code containing
#### arrays of information, or data records.
####
#### Assumptions:
####
#### This script assumes "ssh" connectivity to the HMC, but
#### not necessarily "password-less" login.
####
#### The HMC user is assumed to have the ability to retrieve
#### HMC configuration information.
####
#### Dependencies:
####
#### Connectivity with the HMC using "ssh" is the only
#### communication mechanism supported at this time.
####
#### Products:
####
#### Two output types are provided at this time, Korn Shell
#### coded arrays of information, and colon (:) delimited
#### data records. One or both types may be output from a
#### single execution of the function.
####
#### The two data types are generated on separate data
#### streams. The Korn shell code is generated on the STDOUT
#### steam, the data record formatted output is generated on
#### the STDERR stream.
####
####
#### Configured Usage:
####
#### This function is expected to be called from a Korn Shell
#### function library, but may be incorporated into a
#### stand-alone script if necessary.
####
#### An HMC managed system name must be provided by the user
#### of this function. That name can be provided on the
#### command line, or by selecting it from a menu. If a
#### managed system name is not provided on the command line,
#### a menu is generated on STDERR, and the user must select
#### a system from the menu.
####
#### Details:
####
################################################################
function lsvioslot {
typeset VERSION="1.0"
typeset TRUE="1"
typeset FALSE="0"
typeset EXITCODE="0"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset HMCUSER=""
typeset HMCNAME=""
typeset LPARNAME=""
typeset SYSNAME=""
typeset LPAROUT=""
typeset HMCLIST="${FALSE}"
typeset KORNOUT="${FALSE}"
typeset DATAOUT="${FALSE}"
typeset -L1 D=":"
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
while getopts ":vVu:h:l:s:LkdD:" OPTION
do
case "${OPTION}" in
'u') HMCUSER="${OPTARG}";;
'h') HMCNAME="${OPTARG}";;
'l') LPARNAME="${OPTARG}";;
's') SYSNAME="${OPTARG}";;
'L') HMCLIST="${TRUE}";;
'k') KORNOUT="${TRUE}";;
'd') DATAOUT="${TRUE}";;
'D') D="${OPTARG}";;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
'?') usagemsg_lsvioslot "${0}" && return 1 ;;
':') usagemsg_lsvioslot "${0}" && return 1 ;;
esac
done
shift $(( ${OPTIND} - 1 ))
####
#### Verify the HMC machine name and LPAR name was specified,
#### if not display an error message and return from this script.
#### The HMC machine name and LPAR name are the only required
#### command line parameters, all others are optional.
####
trap "usagemsg_lsvioslot ${0}" EXIT
if [[ "_${HMCNAME}" = "_" ]]
then
print -u 2 "ERROR: HMC machine name not specified"
return 2
fi
#### If neither 'Korn shell code output (-k)' or 'data record output (-d)'
#### was selected on the command line, default to 'Korn shell code output
#### (-k)'.
if (( KORNOUT == FALSE )) && (( DATAOUT == FALSE ))
then
KORNOUT="${TRUE}"
fi
trap "-" EXIT
####
#### Display some program info and the command line arguments specified
#### if "VERBOSE" mode was specified.
####
(( VERYVERB == TRUE )) && set -x
(( VERBOSE == TRUE )) && print -u 2 "# Program........: ${0}"
(( VERBOSE == TRUE )) && print -u 2 "# Version........: ${VERSION}"
(( VERBOSE == TRUE )) && print -u 2 "# HMC Name.......: ${HMCNAME}"
(( VERBOSE == TRUE )) && print -u 2 "# HMC User.......: ${HMCUSER:-}"
(( VERBOSE == TRUE )) && print -u 2 "# System Name....: ${SYSNAME:-}"
(( VERBOSE == TRUE )) && print -u 2 "# LPAR Name......: ${LPARNAME:-}"
################################################################
####
#### If the "-L" option was specified on the command line, display
#### the list of managed system names and return from this function.
####
if (( HMCLIST == TRUE ))
then
lsmanagedsys -L -u "${HMCUSER}" -h "${HMCNAME}"
return 0
fi
####
#### If the managed system name was not specified on the command line,
#### display a selection menu of managed system names, using the
#### array of names obtained earlier. Prompt the user to select
#### a name.
####
if [[ "_${SYSNAME}" = "_" ]]
then
SYSNAME=$( lsmanagedsys -u "${HMCUSER}" -h "${HMCNAME}" )
fi
####
#### Create an array of LPAR names from which to obtain slot information
####
IFS=$' \t\n'
unset LPAR_NAMES
if [[ "_${LPARNAME}" == "_" ]]
then
LPAR_NAMES=( $( exec ssh ${HMCUSER:-hscroot}@${HMCNAME} "lssyscfg -r lpar -m ${SYSNAME} -F name" ) )
else
LPAR_NAMES=( ${LPARNAME} )
fi
#### If the '-d' command line option was specified, indicating a desire for
#### delimited data record formatted output, send a header line containing
#### field names to the STDERR stream.
if (( DATAOUT == TRUE ))
then
print -u 2 -- "# lpar_name${D}lpar_type${D}slot_number${D}slot_type${D}"
fi
#### If the '-k' command line option was specified, indicating a desire for
#### korn shell code output, send a korn shell statement establishing an
#### associative array to STDOUT for the purpose of containing the LPAR
#### names.
(( KORNOUT == TRUE )) && print "typeset -A LPAR_NAME;"
#### Loop through the list of LPAR names obtained from the command line or
#### returned from the HMC managed system for the purpose of reporting the
#### virtual SCSI SLOT numbers and adapter types.
for LPARNAME in "${LPAR_NAMES[@]}"
do
(( VERBOSE == TRUE )) && print -u 2 "# LPAR Name......: ${LPARNAME}"
#### Begin the iteration of the loop by retrieving the LPAR names and their
#### respective environments (vioserver or aixlinux) from the HMC.
LPAROUT=$( exec ssh ${HMCUSER:-hscroot}@${HMCNAME} "lssyscfg -r lpar \
-m ${SYSNAME} \
--filter lpar_names=${LPARNAME} -F name,lpar_env" )
#### If the '-k' command line option was specified, output a korn shell
#### statement defining an element of the LPAR name associative array. The
#### array element will have the LPAR name as the index and the environment
#### type (vioserver or aixlinux) as the element value.
(( KORNOUT == TRUE )) && print "LPAR_NAME[${LPAROUT%,*}]=\"${LPAROUT#*,}\";"
#### Retrieve all virtual SCSI adapter information for an LPAR from the HMC
#### and store this information in a temporary array for later processing.
#### This information will contain SLOT numbers, SLOT types, etc.
unset ARY
nameref ARY="SLOTS_${LPARNAME}"
IFS=",\""
TMPARY[0]=""
TMPARY=( $( exec ssh ${HMCUSER:-hscroot}@${HMCNAME} "lssyscfg -r prof \
-m ${SYSNAME} \
--filter lpar_names=${LPARNAME} \
-F virtual_scsi_adapters" ) )
unset TMPARY[0]
#### Parse each virtual SCSI adapter record stored in the temporary array
#### and extract the adapter SLOT number and SLOT type (client or server).
typeset IDX
typeset SLOT
typeset TYPE
for IDX in "${!TMPARY[@]}"
do
SLOT="${TMPARY[IDX]%%/*}"
TYPE="${TMPARY[IDX]#*/}"
TYPE="${TYPE%%/*}"
#### If the '-k' command line option was specified, output a korn shell
#### statement defining an element of the SLOT by LPAR name indexed array.
#### The array element will have the SLOT number as the index and the slot
#### type type (client or server) as the element value. The array will have
#### a complex name consisting of the literal characters 'SLOT_' followed by
#### the LPAR name. This means a separate array will be generated for each
#### LPAR to contain it's SLOT information.
if (( KORNOUT == TRUE ))
then
print "SLOT_${LPARNAME}[${SLOT}]=\"${TYPE}\";"
fi
#### If the '-d' command line option was specified, output a colon (:)
#### delimited record containing the LPAR name, LPAR type (vioserver or
#### aixlinux), SLOT number, and SLOT type.
if (( DATAOUT == TRUE ))
then
print -u 2 -- "# ${LPARNAME}${D}${LPAROUT#*,}${D}${SLOT}${D}${TYPE}${D}"
fi
#### Continue with the next iteration of the loop which will use the next
#### LPAR name in the list, or if none exist, exit the loop.
done | sort -n
unset ARY
done
return 0
}
################################################################
function usagemsg_lsmanagedsys {
print "
Program: lsmanagedsys
List the managed systems associated with an HMC.
Usage: ${1##*/} [-?vV] -h HMCname -u HMCuser [-L]
Where:
-v = Verbose mode - displays lsmanagedsys function info
-V = Very Verbose Mode - debug output displayed
-h = HMC machine name
-u = HMC user name
-L = Display a list of systems managed by the specified HMC
Author: Dana French (dfrench@mtxia.com)
Copyright 2006, All Rights Reserved
\"AutoContent\" enabled
"
}
################################################################
####
#### Description:
####
#### The purpose of this function is to retrieve a list of
#### HMC managed systems from an HMC, generate a menu using
#### the retrieved system names, prompt the user to select
#### one of the system names, and return the selected system
#### name as the result of this function.
####
#### Assumptions:
####
#### This script assumes "ssh" connectivity to the HMC, but
#### not necessarily "password-less" login.
####
#### The HMC user is assumed to have the ability to retrieve
#### HMC configuration information.
####
#### Dependencies:
####
#### Connectivity with the HMC using "ssh" is the only
#### communication mechanism supported at this time.
####
#### Products:
####
#### A menu of retrieved system names is generated on the
#### STDERR stream, the user is expected to select an item
#### from the displayed menu on the STDIN steam. The
#### selected item, the managed system name, is sent to the
#### STDOUT stream as the result of this function.
####
#### Configured Usage:
####
#### This function is expected to be called from a Korn Shell
#### function library, but may be incorporated into a
#### stand-alone script if necessary.
####
#### An HMC managed system name must be provided by the user
#### of this function. That name can be provided on the
#### command line, or by selecting it from a menu. If a
#### managed system name is not provided on the command line,
#### a menu is generated on STDERR, and the user must select
#### a system from the menu.
####
#### Details:
####
################################################################
function lsmanagedsys
{
typeset VERSION="1.0"
typeset TRUE="1"
typeset FALSE="0"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset HMCLIST="${FALSE}"
typeset HMCUSER=""
typeset HMCNAME=""
typeset SYSLIST
typeset SYSTMP
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
while getopts ":vVLu:h:" OPTION
do
case "${OPTION}" in
'u') HMCUSER="${OPTARG}";;
'h') HMCNAME="${OPTARG}";;
'L') HMCLIST="${TRUE}";;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
[?:#]) usagemsg_lsmanagedsys "${0}" && return 1 ;;
esac
done
shift $(( ${OPTIND} - 1 ))
################################################################
####
#### Obtain a list of managed system names from the HMC
####
SYSLIST=( $( exec ssh ${HMCUSER:-hscroot}@${HMCNAME} "lssyscfg -r sys -F name" ) )
####
#### If the "-L" option was specified on the command line, display
#### the list of managed system names and return from this function.
####
typeset SYSTMP
if (( HMCLIST == TRUE ))
then
for SYSTMP in "${SYSLIST[@]}"
do
print -- "${SYSTMP}"
done
return 0
fi
####
#### Display a selection menu of managed system names, using the
#### array of system names obtained earlier. Prompt the user to
#### select a name.
####
PS3=$'\n'"Select a system by number: "
print -u 2 -- "\nSelect a system managed by the HMC \"${HMCNAME}\".\n"
select SYSNAME in "${SYSLIST[@]}"
do
if [[ "_${SYSNAME}" == "_" ]]
then
print -u 2 "\n# ERROR: Invalid selection\n"
else
break
fi
done >&2
#### Send the system name selected by the user to STDOUT, to be
#### interpreted by the calling function as the result of this function.
print -- "${SYSNAME}"
return 0
}
################################################################
mapluns "${@}"