#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2017,2019,2020,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # ############################################################################### # @(#) 64438b3 43haes/usr/sbin/cluster/events/utils/clhmccmd.sh, 726, 2147A_aha726, Oct 13 2021 08:38 AM ############################################################################### ######################################################################### # # COMPONENT_NAME: hacmp.events # # FUNCTIONS: # # usage # parse_cmd_line # format_list # get_local_partition # get_local_hmc_list # check_enterprise_pool # check_partition # check_managed_system # check_profile # check_shared_processor_pool # get_enterprise_pool # get_local_managed_system # get_lpars_state # get_managed_system # get_profile # get_shared_processor_pool # get_free_sys_mem # get_free_sys_proc_units # get_free_pool_proc_units # gather_and_convert # execute_cmds # sort_and_output # process_query # process_change # process_acquire # process_release # get_hmc_param # update_hmc_list # get_effective_version # hmccmdexec # clhmcexec # ######################################################################### #================================================ # The following, commented line enforces coding # standards when this file is edited via vim. #================================================ # vim:tabstop=4:shiftwidth=4:expandtab:smarttab #================================================ #============================================================================= # # NAME # clhmccmd - perform HMC commands on cluster ROHA resources # # SYNOPSIS # To query configuration information for current LPAR/Managed System/EPCoD/etc: # clhmccmd -o query -a {ALL|GEN|PROC|MEM|HMC|CEC|LPAR|PROF|SPP|TRIAL|ONOFF|EPCOD|} # [-E ] [-M ] [-L ] [-P ] [-S ] [-h] [-H ] # # To change configuration parameter: # clhmccmd -o change -a "attr_name1=value:attr_name2=value:..." [-H ] # # To acquire resources (allocate DLPAR resources, activate On/Off resources, acquire EPCoD resources) # or release these resources: # clhmccmd -o {acquire|release} [-f] -r {dlpar|onoff|epcod} [-m ] [-p ] # [-q ] [-d ] [-t ] [-H ] # # To halt current partition: # clhmccmd -o halt [-L ] [-H ] # # DESCRIPTION # This clhmccmd command line interfaces HMC to perform HMC commands for the # account of PowerHA SystemMirror 'Resource Optimized High Availability' # (ROHA) functionality. # # This clhmccmd command line is the common pipe for PowerHA SystemMirror to # interface HMCs. # # This clhmccmd command line can run on any node of the cluster. # # PowerHA SystemMirror configuration must be done as far as HMCs are concerned: # - HMCs have to be configured either # at the cluster level, # or at the site level, # or at the node level. # - But this is always possible to use the [-H hmcs] option otherwise. # # This clhmccmd command line encapsulates with ssh all commands run on HMCs, # but the ssh link has to be properly configured first. # # This clhmccmd command line encapsulates a retry mechanism, and is able to # takeover on an other HMC (the next in the list) in case of repeated failure. # # This clhmccmd command line translates applicative level request to commands # comprehensible by the HMC, taking into account the version of HMC, and is # able to perform the following types of operations: # - Query operation on configuration attributes. # - Change operation on configuration attributes. # - Allocation of memory and processor DLPAR resources (in shared and dedicated processing modes). # - Activation of memory and processor On/Off CoD resources. # - Acquisition of memory and processor EPCoD resources. # - Release of memory and processor DLPAR resources (in shared and dedicated processing modes), # On/Off resources, EPCoD resources. # - Administrative actions on CEC to immediately halt LPARs. # # OPTIONS # -a The colon-separated list of attributes. Only valid and mandatory with # -o {query|change} option. # Valid values for -o query option are: # hmc_list, hmc_version. # local_sys_name, sys_name, # sys_lpar_names, sys_state, # sys_type_model, cod_mem_capable, # cod_proc_capable, mem_region_size, # installed_sys_mem, configurable_sys_mem, # sys_firmware_mem, curr_avail_sys_mem, # curr_free_sys_mem, deconfig_sys_mem, # installed_sys_proc_units, deconfig_sys_proc_units, # configurable_sys_proc_units, curr_avail_sys_proc_units, # curr_free_sys_proc_units, min_proc_units_per_virtual_proc. # local_lpar_name, lpar_name, # lpar_id, uuid, # lpar_state, curr_profile, # lpar_avail_priority, curr_proc_mode, # curr_min_mem, curr_mem, # curr_max_mem, curr_min_procs, # curr_procs, curr_max_procs, # curr_min_proc_units, curr_proc_units, # curr_max_proc_units, curr_shared_proc_pool_name. # local_prof_name, prof_name, # prof_proc_mode, prof_sharing_mode, # prof_shared_procpool, prof_minimum_procs, # prof_desired_procs, prof_maximum_procs, # prof_minimum_proc_units, prof_desired_proc_units, # prof_maximum_prof_units, prof_minimum_mem, # prof_desired_mem, prof_maximum_mem. # local_procpool_name, procpool_name, # max_pool_proc_units, curr_free_pool_proc_units, # curr_reserved_pool_proc_units. # mem_trial_state, activated_trial_mem, # mem_trial_days_left, mem_trial_hours_left, # proc_trial_state, activated_trial_procs, # proc_trial_days_left, proc_trial_hours_left. # proc_onoff_state, activated_onoff_procs, # avail_procs_for_onoff, unreturned_onoff_procs, # onoff_request_proc_days_left, onoff_proc_day_hours_left, # onoff_proc_days_avail, # mem_onoff_state, activated_onoff_mem, # avail_mem_for_onoff, unreturned_onoff_mem, # onoff_request_mem_days_left, onoff_mem_day_hours_left, # onoff_mem_days_avail. # local_codpool_name, codpool_name, # codpool_sys_names, mobile_state, # master_mc_name, backup_master_mc_name, # mobile_mem, unreturned_mobile_mem, # avail_mobile_mem, sys_inactive_mem, # sys_mobile_mem, sys_unreturned_mobile_mem, # mobile_procs, unreturned_mobile_procs, # avail_mobile_procs, sys_inactive_procs, # sys_mobile_procs, sys_unreturned_mobile_procs. # Valid values for -o change option are: # max_pool_proc_units reserved_pool_proc_units. # -d The number of days for On/Off CoD request. Only valid and mandatory # with -o acquire and -l onoff. # -E The EPCoD name. May be specified if information from another # EPCoD than the one the Managed System the LPAR belongs to are needed. # -f Force allocation/release of resources to the best effort even if failure. # -h Display help usage. # -H The space-separated list of HMCs to interrogate. # -l Display labels. # -L The LPAR name. May be specified if information from another LPAR # than the one on which the command is issued are needed. # -m The amount of memory (in MBytes). Only valid with -o acquire and -o release. # -M The Managed System name. May be specified if information from another Managed System # than the one the LPAR belongs to are needed. # -o The operation to perform. Valid values are query, change, acquire and release. # The query operation displays information about configuration by # interrogating the first HMC in the list. Option -a is mandatory. # The change operation sets attributes to new values. Option -a is # mandatory. # The acquire operation tries to allocate/activate/acquire/ resources for the account # of the LPAR. If no -m, -p or -q option are set, acquire all possible # resources. If -l option is set to onoff, -d option is mandatory. # The release operation tries to release resources for the account of # the LPAR. If no -m, -p or -q option is set, release all possible # resources. # The halt operation tries to immediately shutdown the LPAR. # -p The decimal number of processing units. Only valid with -o acquire and -o release. # -P The profile name. May be specified if information from another profile than # the one on which the command is issued are needed. # -q The number of processors. Only valid with -o acquire and -o release. # -r The type of resources. Only valid and mandatory with -o acquire and -o release. # Valid values are dlpar for Dynamic LPAR resources, onoff for On/Off CoD resources, # epcod for Enterprise Pool CoD resources. # -s Safe option to tell that no check is to be done on parameter. # -S The shared processor pool name. May be specified if information from another # shared processor pool than the one the partition belongs to are needed. # -t The timeout for operation on DLPAR memory and processors. Only valid with # -o acquire and -o release and -r dlpar. This timeout will automatically be # incremented by the maximum resources value. # # EXIT STATUS # This command has the following return codes: # 0 Success # 1 Error - Wrong parameter # 2 Error - Last HMC tried cannot be pinged # 3 Error - Remote command cannot be ssh'ed on the last HMC tried # 4 Error - Remote command returned a resource busy error on the last HMC tried # 5 Error - Remote command returned a managed system busy error on the last HMC tried # 6 Error - Remote command returned a not enough resources error on the last HMC tried # 7 Error - Remote command returned an other type of error on the last HMC tried # # EXAMPLES # To query multiple configuration information: # clhmccmd -o query -a hmc_version:curr_proc_mode:activated_onoff_mem:lpar_state # # To query all configuration information with labels: # clhmccmd -o query -a ALL -l # # To query multiple configuration information for a specific Managed System: # clhmccmd -o query -a sys_state:sys_type_model -M 3node-9117-MMB-100082P # # To change maximum size of shared processor pool: # clhmccmd -o change -a "max_pool_proc_units=8.5" # # To allocate 9.75 GBytes of memory, 2.2 processing units and 4 virtual CPUs of DLPAR resources: # clhmccmd -o acquire -m 9984 -p 2.2 -q 4 -r dlpar # # To activate 32 GBytes of On/Off CoD memory resources for 18 days: # clhmccmd -o acquire -m 32768 -d 18 -r onoff # # To acquire 32 GBytes of EPCoD memory resources for 18 days: # clhmccmd -o acquire -m 32768 -r epcod # # To release 100 GBytes of DLPAR memory resources with a 50 minutes timeout: # clhmccmd -o release -m 102400 -r dlpar -t 50 # # To release 7 Enterprise Pool CoD processors: # clhmccmd -o release -r epcod -q 7 # # To shutdown current partition: # clhmccmd -o halt # # Questions? Comments? Expressions of Astonishment? mailto:hafeedbk@us.ibm.com # #============================================================================= #============================================================================= # # Name: usage # # Description: Prints usage. # # Arguments: None # # Returns: None # #============================================================================= function usage { printf "%s: Usage:\n" "$PROGNAME" printf "\tclhmccmd -o query -a {ALL|GEN|PROC|MEM|HMC|CEC|LPAR|PROF|SPP|TRIAL|ONOFF|EPCOD|} [-l] [-H ] [-E ] [-M ] [-L ] [-P ] [-S ]\n" printf "\tclhmccmd -o change -a \"attr_name1=value:attr_name2=value:...\" [-H ]\n" printf "\tclhmccmd -o {acquire|release} [-f] -r {dlpar|onoff|epcod} [-m ] [-p ] [-q ] [-d ] [-t ] [-H ]\n" printf "\tclhmccmd -o halt [-L ] [-H ]\n" printf "\n" printf "Note: -m must be passed in MB, 1GB=1024MB.\n" printf "Note: verbose output is shown by setting VERBOSE_LOGGING=high.\n" printf "Note: to display output messages, run clhmccmd with \" 3>&2\"" } # End of "usage()" #============================================================================= # # Name: parse_cmd_line # # Description: Parse and check the command line arguments. # # Arguments: $@ [IN] list of arguments # # Environment: g_attributes # g_duration # g_enterprise_pool # g_hmc_list # g_labels # g_partition # g_memory # g_managed_system # g_operation # g_proc_units # g_profile # g_quantity # g_resource # g_shared_proc_pool # g_timeout # # Returns: RC_SUCCESS # RC_PARAM_ERROR # #============================================================================= function parse_cmd_line { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS duplicate_args=$(echo $* | tr ' ' '\n' | grep "^-" | uniq -d) if [[ -n $duplicate_args ]]; then echo ERROR: $duplicate_args option is duplicate. exit $RC_PARAM_ERROR fi #======================================================= # Get options #======================================================= while getopts ":a:d:E:fhH:lL:m:M:o:p:P:q:r:sS:t:" opt ; do case $opt in a) g_attributes=$OPTARG ;; # attributes to list d) g_duration=$OPTARG ;; # number of days for onoff requests E) g_enterprise_pool=$OPTARG ;; # enterprise pool name f) g_force=1 ;; # force allocation/release h) usage ; exit $RC_SUCCESS ;; # usage H) if [[ -z $g_hmc_list ]] ; then # list of HMCs g_hmc_list=${g_hmc_list:+${g_hmc_list} }${OPTARG//[,:]/ } fi ;; l) g_labels=1 ;; # display labels L) g_partition=$OPTARG ;; # partition name m) g_memory=$OPTARG ;; # MBytes of memory M) g_managed_system=$OPTARG ;; # managed system name o) g_operation=$OPTARG ;; # operation {query|change|acquire|release} p) g_proc_units=$OPTARG ;; # processing units for shared proc LPARs P) g_profile=$OPTARG ;; # profile name q) g_quantity=$OPTARG ;; # quantity of CPUs r) g_resource=$OPTARG ;; # resource type {dlpar|onoff|epcod} s) g_safe_option=1 ;; S) g_shared_proc_pool=$OPTARG ;; # shared processor pool name t) g_timeout=$OPTARG ;; # timeout for DLPAR operations \?) dspmsg $ROHA_MSGS -s $ROHA_SET 400 \ "%1\$s: ERROR: unknown -%2\$s parameter.\n" \ "$PROGNAME" "$OPTARG" >&3 exit $RC_PARAM_ERROR ;; :) dspmsg $ROHA_MSGS -s $ROHA_SET 401 \ "%1\$s: ERROR: -%2\$s option requires an argument.\n" \ "$PROGNAME" "$OPTARG" >&3 exit $RC_PARAM_ERROR ;; esac done shift $((OPTIND-1)) if [[ -n $1 ]]; then echo "WARNING: Unknown extra parameter $1 \n" fi #======================================================= # Check operation #======================================================= if [[ -z $g_operation ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 402 \ "%1\$s: ERROR: missing operation.\n" \ "$PROGNAME" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 404 \ "\tSupported operations for -o flag are: %1\$s.\n" \ "$OPERATION_LIST" >&3 exit $RC_PARAM_ERROR fi case $g_operation in q*) #======================================================= # Check query options #======================================================= g_operation="query" if [[ -z $g_attributes ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 405 \ "%1\$s: ERROR: missing attribute for %2\$s operation.\n" \ "$PROGNAME" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 407 \ "\tSupported attributes for -a flag are:\n%1\$s\n" \ "$(format_list "$QUERY_ATTR_LIST")" >&3 exit $RC_PARAM_ERROR fi for attribute in ${g_attributes//:/ } ; do #======================================================= # Convert generic g_attributes #======================================================= case $attribute in ALL) g_attributes=${g_attributes/ALL/${QUERY_ATTR_LIST// /:}} ;; HMC) g_attributes=${g_attributes/HMC/${HMC_ATTRS// /:}} ;; CEC) g_attributes=${g_attributes/CEC/${MANAGED_SYSTEM_ATTRS// /:}} ;; LPAR) g_attributes=${g_attributes/LPAR/${PARTITION_ATTRS// /:}} ;; PROF) g_attributes=${g_attributes/PROF/${PROFILE_ATTRS// /:}} ;; SPP) g_attributes=${g_attributes/SPP/${SHARED_PROC_POOL_ATTRS// /:}} ;; TRIAL) g_attributes=${g_attributes/TRIAL/${TRIAL_COD_ATTRS// /:}} ;; ONOFF) g_attributes=${g_attributes/ONOFF/${ONOFF_COD_ATTRS// /:}} ;; EPCOD) g_attributes=${g_attributes/EPCOD/${ENTERPRISE_POOL_ATTRS// /:}} ;; GEN) g_attributes=${g_attributes/GEN/${GENERAL_ATTRS// /:}} ;; PROC) g_attributes=${g_attributes/PROC/${PROCESSOR_ATTRS// /:}} ;; MEM) g_attributes=${g_attributes/MEM/${MEMORY_ATTRS// /:}} ;; AVAIL) g_attributes=${g_attributes/AVAIL/${AVAIL_ATTRS// /:}} ;; CURRENT) g_attributes=${g_attributes/CURRENT/${CURRENT_ATTRS// /:}} ;; *) if [[ $attribute != @(${QUERY_ATTR_LIST// /\|}) ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 406 \ "%1\$s: ERROR: unsupported %2\$s attribute for %3\$s operation.\n" \ "$PROGNAME" "$attribute" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 407 \ "\tSupported attributes for -a flag are:\n%1\$s\n" \ "$(format_list "$QUERY_ATTR_LIST")" >&3 exit $RC_PARAM_ERROR fi esac done ;; c*) #======================================================= # Check change options #======================================================= g_operation="change" if [[ -z $g_attributes ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 405 \ "%1\$s: ERROR: missing attribute for %2\$s operation.\n" \ "$PROGNAME" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 407 \ "\tSupported attributes for -a flag are:\n%1\$s\n" \ "$(format_list "$CHANGE_ATTR_LIST")" >&3 exit $RC_PARAM_ERROR fi for attribute in ${g_attributes//:/ } ; do print -- $attribute | IFS='=' read key value if [[ $key != @(${CHANGE_ATTR_LIST// /\|}) ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 406 \ "%1\$s: ERROR: unsupported %2\$s attribute for %3\$s operation.\n" \ "$PROGNAME" "$key" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 407 \ "\tSupported attributes for -a flag are:\n%1\$s\n" \ "$(format_list "$CHANGE_ATTR_LIST")" >&3 exit $RC_PARAM_ERROR fi done ;; a*) #======================================================= # Check acquire options #======================================================= g_operation="acquire" if [[ -z $g_resource ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 408 \ "%1\$s: ERROR: missing resource type for %2\$s operation.\n" \ "$PROGNAME" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 410 \ "\tSupported resource types for -r flag are: %1\$s.\n" \ "$RESOURCE_LIST" >&3 exit $RC_PARAM_ERROR fi if [[ $g_resource != @(dlpar|onoff|epcod) ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 409 \ "%1\$s: ERROR: unsupported %2\$s resource type for %3\$s operation.\n" \ "$PROGNAME" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 410 \ "\tSupported resource types for -r flag are: %1\$s.\n" \ "$RESOURCE_LIST" >&3 exit $RC_PARAM_ERROR fi if (( $g_memory == 0 && $g_quantity == 0 && $g_proc_units == 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 411 \ "%1\$s: ERROR: missing resource quantity for %2\$s operation. Provide -m, -q or -p option.\n" \ "$PROGNAME" "$g_operation" >&3 exit $RC_PARAM_ERROR fi if [[ $g_resource == onoff ]] && (( $g_duration == -1 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 412 \ "%1\$s: ERROR: missing request duration for On/Off CoD acquire operation. Provide -d option.\n" \ "$PROGNAME" >&3 exit $RC_PARAM_ERROR fi ;; r*) #======================================================= # Check release options #======================================================= g_operation="release" if [[ -z $g_resource ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 408 \ "%1\$s: ERROR: missing resource type for %2\$s operation.\n" \ "$PROGNAME" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 410 \ "\tSupported resource types for -r flag are: %1\$s.\n" \ "$RESOURCE_LIST" >&3 exit $RC_PARAM_ERROR fi if [[ $g_resource != @(dlpar|onoff|epcod) ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 409 \ "%1\$s: ERROR: unsupported %2\$s resource type for %3\$s operation.\n" \ "$PROGNAME" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 410 \ "\tSupported resource types for -r flag are: %1\$s.\n" \ "$RESOURCE_LIST" >&3 exit $RC_PARAM_ERROR fi if (( $g_memory == 0 && $g_quantity == 0 && $g_proc_units == 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 411 \ "%1\$s: ERROR: missing resource quantity for %2\$s operation. Provide -m, -q or -p option.\n" \ "$PROGNAME" "$g_operation" >&3 exit $RC_PARAM_ERROR fi ;; h*) #======================================================= # Check halt options #======================================================= g_operation="halt" ;; *) dspmsg $ROHA_MSGS -s $ROHA_SET 403 \ "%1\$s: ERROR: unsupported %2\$s operation.\n" \ "$PROGNAME" "$g_operation" >&3 dspmsg $ROHA_MSGS -s $ROHA_SET 404 \ "\tSupported operations for -o flag are: %1\$s.\n" \ "$OPERATION_LIST" >&3 exit $RC_PARAM_ERROR esac #======================================================= # Check HMC list & partition #======================================================= if [[ -n $g_hmc_list ]] ; then if [[ -n $g_partition ]] ; then if (( g_safe_option == 0)); then check_partition $g_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 414 \ "%1\$s: ERROR: unknown %2\$s LPAR. Provide valid name through -L option.\n" \ "$PROGNAME" "$g_partition" >&3 exit $RC_PARAM_ERROR fi fi else get_local_partition g_local_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 414 \ "%1\$s: ERROR: unknown %2\$s LPAR. Provide valid name through -L option.\n" \ "$PROGNAME" "$g_local_partition" >&3 exit $RC_PARAM_ERROR fi fi else #======================================================= # cl_get_hmc_list needs a node name as argument. #======================================================= if [[ -n $g_partition ]] ; then #======================================================= # nodename/lparname match and nodename/cecname match are # stored into HACMPdynresop ODM # We use cl_dynresop to retrieve match between lparname # and nodename into HACMPdynresop ODM #======================================================= nodename=$(LC_ALL=C cl_dynresop -l $g_partition -N) rc=$? if (( rc != 0 )) || [[ -z $nodename ]] ; then # : best can do, nodename is set to g_partition $g_partition # nodename=$g_partition rc=$RC_SUCCESS fi g_hmc_list=$(cl_get_hmc_list -n $nodename 2>/dev/null) if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 413 \ "%1\$s: ERROR: no list of HMC defined for %2\$s node. Provide -H option.\n" \ "$PROGNAME" "$nodename" >&3 exit $RC_PARAM_ERROR fi check_partition $g_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 414 \ "%1\$s: ERROR: unknown %2\$s LPAR. Provide valid name through -L option.\n" \ "$PROGNAME" "$g_partition" >&3 exit $RC_PARAM_ERROR fi else get_local_hmc_list g_hmc_list if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 413 \ "%1\$s: ERROR: no list of HMC defined for %2\$s node. Provide -H option.\n" \ "$PROGNAME" "$(get_local_nodename)" >&3 exit $RC_PARAM_ERROR fi get_local_partition g_local_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 414 \ "%1\$s: ERROR: unknown %2\$s LPAR. Provide valid name through -L option.\n" \ "$PROGNAME" "$g_local_partition" >&3 exit $RC_PARAM_ERROR fi fi fi #======================================================= # Check managed system #======================================================= if [[ -n $g_managed_system && -z $g_enterprise_pool ]] ; then if (( g_safe_option == 0)); then check_managed_system $g_managed_system if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 416 \ "%1\$s: ERROR: unknown %2\$s Managed System. Provide valid name through -M option.\n" \ "$PROGNAME" "$g_managed_system" >&3 exit $RC_PARAM_ERROR fi fi fi #======================================================= # Check enterprise pool #======================================================= if [[ -n $g_enterprise_pool ]] ; then if (( g_safe_option == 0)); then check_enterprise_pool $g_enterprise_pool if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 415 \ "%1\$s: ERROR: unknown %2\$s Enterprise Pool CoD. Provide valid name through -E option.\n" \ "$PROGNAME" "$g_enterprise_pool" >&3 exit $RC_PARAM_ERROR fi fi fi #======================================================= # Check profile #======================================================= if [[ -n $g_profile ]] ; then if [[ -n $g_partition ]] ; then if (( g_safe_option == 0)); then check_profile $g_profile $g_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 417 \ "%1\$s: ERROR: unknown %2\$s Profile for %3\$s LPAR. Provide valid name through -P option.\n" \ "$PROGNAME" "$g_profile" "$g_partition" "$prof_name" >&3 exit $RC_PARAM_ERROR fi fi else get_local_partition g_local_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 414 \ "%1\$s: ERROR: unknown %2\$s LPAR. Provide valid name through -L option.\n" \ "$PROGNAME" "$g_local_partition" >&3 exit $RC_PARAM_ERROR fi check_profile $g_profile $g_local_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 417 \ "%1\$s: ERROR: unknown %2\$s Profile for %3\$s LPAR. Provide valid name through -P option.\n" \ "$PROGNAME" "$g_profile" "$g_local_partition" >&3 exit $RC_PARAM_ERROR fi fi fi #======================================================= # Check shared processor pool #======================================================= if [[ -n $g_shared_proc_pool ]] ; then if [[ -n $g_partition ]] ; then if (( g_safe_option == 0)); then check_shared_processor_pool $g_shared_proc_pool $g_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 418 \ "%1\$s: ERROR: unknown %2\$s Shared Processor Pool for %3\$s LPAR. Provide valid name through -S option.\n" \ "$PROGNAME" "$g_shared_proc_pool" "$g_partition" >&3 exit $RC_PARAM_ERROR fi fi else get_local_partition g_local_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 414 \ "%1\$s: ERROR: unknown %2\$s LPAR. Provide valid name through -L option.\n" \ "$PROGNAME" "$g_local_partition" >&3 exit $RC_PARAM_ERROR fi check_shared_processor_pool $g_shared_proc_pool $g_local_partition if (( $? > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 418 \ "%1\$s: ERROR: unknown %2\$s Shared Processor Pool for %3\$s LPAR. Provide valid name through -S option.\n" \ "$PROGNAME" "$g_shared_proc_pool" "$g_local_partition" >&3 exit $RC_PARAM_ERROR fi fi fi #======================================================= # Check consistency when -L and -M options are provided #======================================================= if (( g_safe_option == 0)); then if [[ -n $g_managed_system && -n $g_partition ]] ; then # partition should belong to managed system typeset sys_name= get_managed_system sys_name $g_partition if [[ $sys_name != $g_managed_system ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 419 \ "%1\$s: ERROR: %2\$s LPAR does not belong to %3\$s Managed System but $4\$s. Provide valid name through -L or -M option.\n" \ "$PROGNAME" "$g_partition" "$g_managed_system" "$sys_name" >&3 exit $RC_PARAM_ERROR fi fi fi #======================================================= # Check consistency when -E and -M options are provided #======================================================= if (( g_safe_option == 0)); then if [[ -n $g_enterprise_pool && -n $g_managed_system ]] ; then # enterprise pool should belong to managed system typeset epcod_name= get_enterprise_pool epcod_name $g_managed_system if [[ $epcod_name != $g_enterprise_pool ]] ; then dspmsg $ROHA_MSGS -s $ROHA_SET 420 \ "%1\$s: ERROR: %2\$s Managed System does not belong to %3\$s Enterprise Pool CoD but %4\$s. Provide valid name through -M or -E option.\n" \ "$PROGNAME" "$g_managed_system" "$g_enterprise_pool" "$epcod_name" >&3 exit $RC_PARAM_ERROR fi fi fi return $rc } # End of "parse_cmd_line()" #============================================================================= # # Name: format_list # # Description: Prints format_list. # # Arguments: $1 [IN] list of elements # # Returns: None # #============================================================================= function format_list { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset list=$1 list="$(print "${list// /\\n}" | sort -u)" print $list | read -A array for (( i=0; i<${#array[@]}; i+=2 )) ; do printf "\t%-32s %-32s\n" "${array[$i]}" "${array[$((i+1))]}" done } # End of "format_list()" #============================================================================= # # Name: get_local_partition # # Description: Obtain local partition name. The partition name is got from # 'uname -L'. # # Arguments: $1 [INOUT] lpar_name - reference to the local partition name. # # Environment: HOSTNAME # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_local_partition { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n lpar_name=$1 if [[ -z $lpar_name ]] ; then #======================================================= : It refers to this one. Get it from uname. #======================================================= lpar_name=$(uname -L | cut -d \ -f2 2>/dev/null) if [[ -z $lpar_name ]] ; then #======================================================= : If failed, return failure. #======================================================= rc=$RC_FAILURE fi fi return $rc } # End of "get_local_partition()" #============================================================================= # # Name: get_local_hmc_list # # Description: Obtain HMC list of the current partition. The HMC list is either # retrieved from HACMPdynresop ODM where it was previously saved, # or default to null. # # Arguments: $1 [INOUT] hmc_list - reference to a space-separated list of HMCs. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_local_hmc_list { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n hmc_list=$1 if [[ -z $hmc_list ]] ; then #======================================================= : First, look into HACMPdynresop ODM. #======================================================= hmc_list=$(ODMDIR="/etc/es/objrepos" clodmget -q "key=PREFERRED_HMC_LIST" -nf value HACMPdynresop 2>/dev/null) rc=$? if (( $rc > 0 )) || [[ -z $hmc_list ]] ; then #======================================================= : Then, look at node, site or cluster level ODM. If no : partition are provided, it will look by default for : the local partition. #======================================================= hmc_list=$(cl_get_hmc_list 2>/dev/null) rc=$? if (( $rc > 0 )) || [[ -z $hmc_list ]] ; then #======================================================= : Then, unset and return failure. #======================================================= hmc_list="" rc=$RC_FAILURE fi fi fi return $rc } # End of "get_local_hmc_list()" #============================================================================= # # Name: check_enterprise_pool # # Description: Check enterprise pool name by asking HMC. # # Arguments: $1 [IN] epcod_name - enterprise pool name to check for. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function check_enterprise_pool { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset epcod_name=$1 #======================================================= : Check enterprise pool name #======================================================= clhmcexec "lscodpool --level pool -p $epcod_name -F name" res if (( $? > 0 )) ; then rc=$RC_FAILURE fi return $rc } # End of "check_enterprise_pool()" #============================================================================= # # Name: check_partition # # Description: Check partition name by asking HMC. # # Arguments: $1 [IN] lpar_name - partition name to check for. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function check_partition { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset lpar_name=$1 typeset sys_name_ref="" typeset res="" #=================================================== # nodename/lparname match and nodename/cecname match # are stored into HACMPdynresop ODM # we use cl_dynresop to retrieve match between # lparname and cecname into HACMPdynresop ODM #=================================================== [[ -z $lpar_name ]] && get_local_partition lpar_name sys_name_ref=$(LC_ALL=C cl_dynresop -l $lpar_name -C) if (( $? != 0 )) ; then # : If ever not possible to retrieve partition using cl_dynresop, : try to loop against all cecs of hmc # typeset -i found=0 clhmcexec "lssyscfg -r sys -F name" res if (( $? == $RC_SUCCESS )) ; then #======================================================= # Ask HMC if the partition belongs to the managed system. #======================================================= print "$res" | \ while read sys_name_ref ; do { clhmcexec "lssyscfg -r lpar -m $sys_name_ref -F name" res rc=$? if (( rc == $RC_SUCCESS )) ; then print "$res" | \ while read lpar_name_ref ; do if [[ $lpar_name == $lpar_name_ref ]] ; then found=1 break 2 fi done fi } < /dev/null ; done # Avoid ssh to break while loop by redirecting standard input fi if (( found == 0 )) ; then rc=$RC_FAILURE fi else # : Retrieve complete sys_name_ref $sys_name_ref against HMC # clhmcexec "lssyscfg -r sys -m $sys_name_ref -F name" sys_name_ref if (( $? > 0 )) ; then rc=$RC_FAILURE else # : Check lpar_name $lpar_name against HMC # clhmcexec "lssyscfg -r lpar -m $sys_name_ref --filter lpar_names=$lpar_name -F name" res if (( $? > 0 )) ; then rc=$RC_FAILURE fi fi fi return $rc } # End of "check_partition()" #============================================================================= # # Name: check_managed_system # # Description: Check managed system name by asking HMC. # # Arguments: $1 [IN] sys_name - managed system name to check for. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function check_managed_system { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset sys_name=$1 #======================================================= : Check managed system name #======================================================= clhmcexec "lssyscfg -r sys -m $sys_name -F name" res if (( $? > 0 )) ; then rc=$RC_FAILURE fi return $rc } # End of "check_managed_system()" #============================================================================= # # Name: check_profile # # Description: Check profile name is valid for the partition by asking HMC. # # Arguments: $1 [IN] prof_name - profile name to check for. # $2 [IN] lpar_name - lpar name to check for. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function check_profile { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset prof_name=$1 typeset lpar_name=$2 typeset sys_name="" #======================================================= : Obtain managed system of the partition #======================================================= get_managed_system sys_name $lpar_name if (( $? > 0 )) ; then rc=$RC_FAILURE else #======================================================= : Check profile name #======================================================= clhmcexec "lssyscfg -r prof -m $sys_name --filter lpar_names=$lpar_name,profile_names=$prof_name -F name" res if (( $? > 0 )) ; then rc=$RC_FAILURE fi fi return $rc } # End of "check_profile()" #============================================================================= # # Name: check_shared_processor_pool # # Description: Check shared processor pool name is valid for the partition by asking HMC. # # Arguments: $1 [IN] spp_name - shared processor pool name to check for. # $2 [IN] lpar_name - lpar name to check for. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function check_shared_processor_pool { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset spp_name=$1 typeset lpar_name=$2 typeset sys_name="" #======================================================= : Obtain managed system of the partition #======================================================= get_managed_system sys_name $lpar_name if (( $? > 0 )) ; then rc=$RC_FAILURE else #======================================================= : Check shared processor pool name #======================================================= clhmcexec "lshwres -r procpool -m $sys_name --filter pool_names=$spp_name -F name" res if (( $? > 0 )) ; then rc=$RC_FAILURE fi fi return $rc } # End of "check_shared_processor_pool()" #============================================================================= # # Name: get_managed_system # # Description: Obtain managed system name of a partition. The name is gotten # from the ODM, or from HMC, or default to null. # # Arguments: $1 [INOUT] sys_name - reference to the managed system name. # $2 [IN] lpar_name - partition name to search managed system for. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_managed_system { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n sys_name=$1 typeset lpar_name=$2 typeset local_lpar_name="" #=================================================== # nodename/lparname match and nodename/cecname match # are stored into HACMPdynresop ODM # we use cl_dynresop to retrieve match between # lparname and cecname into HACMPdynresop ODM #=================================================== [[ -z $lpar_name ]] && get_local_partition lpar_name sys_name=$(LC_ALL=C cl_dynresop -l $lpar_name -C) rc=$? if (( rc == 0 )); then clhmcexec "lssyscfg -r sys -m $sys_name -F name" sys_name if (( $? != 0 )) ; then rc=$RC_FAILURE fi fi if [[ -z $sys_name || $rc != 0 ]]; then # : If ever not possible to retrieve cec name using cl_dynresop, : try to loop against all cecs of hmc # typeset sys_name_ref="" typeset res="" typeset -i found=0 #======================================================= : Check if lpar_name is the local one #======================================================= get_local_partition local_lpar_name rc=$? if (( rc == $RC_SUCCESS )) && [[ $local_lpar_name == $lpar_name ]] ; then #======================================================= : If looking for local MS name, use dedicated function #======================================================= get_local_managed_system sys_name rc=$? else #======================================================= : If any error while getting local_lpar_name, go through : the long process anyway #======================================================= rc=$RC_SUCCESS fi if [[ -z $sys_name ]] ; then #======================================================= : Then, ask the HMC and go through all lpars from all : managed system to find our partition. Break when found. #======================================================= typeset -i found=0 clhmcexec "lssyscfg -r sys -F name" res rc=$? if (( rc == $RC_SUCCESS )) ; then #======================================================= # Ask HMC if the partition belongs to the managed system. #======================================================= print "$res" | \ while read sys_name_ref ; do { clhmcexec "lssyscfg -r lpar -m $sys_name_ref -F name" res rc=$? if (( rc == $RC_SUCCESS )) ; then print "$res" | \ while read lpar_name_ref ; do if [[ $lpar_name == $lpar_name_ref ]] ; then sys_name=$sys_name_ref found=1 break 2 fi done fi } < /dev/null ; done # Avoid ssh to break while loop by redirecting standard input fi if (( found == 0 )) || [[ -z $sys_name ]] ; then #======================================================= : Then, unset and return failure. #======================================================= sys_name="" rc=$RC_FAILURE fi else clhmcexec "lssyscfg -r sys -m $sys_name -F name" sys_name if (( $? != 0 )) ; then rc=$RC_FAILURE fi fi fi # : returning sys_name=$sys_name # return $rc } # End of "get_managed_system()" #============================================================================= # # Name: get_local_managed_system # # Description: Obtain local managed system name. The name is gotten # from the ODM, or from HMC, or default to null. # # Arguments: $1 [INOUT] sys_name reference to the managed system name. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_local_managed_system { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n sys_name=$1 typeset LOCAL_MANAGED_SYSTEM_MTM="" typeset LOCAL_MANAGED_SYSTEM_SN="" #======================================================= : First, look into ODM if it has been persisted #======================================================= sys_name=$(ODMDIR="/etc/es/objrepos" clodmget -q "key=MANAGED_SYSTEM" -nf value HACMPdynresop 2>/dev/null) rc=$? if (( rc != $RC_SUCCESS )) || [[ -z $sys_name ]] ; then LOCAL_MANAGED_SYSTEM_MTM=$(uname -M) (( $? == 0 )) && LOCAL_MANAGED_SYSTEM_MTM=${LOCAL_MANAGED_SYSTEM_MTM#*,} LOCAL_MANAGED_SYSTEM_SN=$(uname -u) (( $? == 0 )) && LOCAL_MANAGED_SYSTEM_SN=${LOCAL_MANAGED_SYSTEM_SN#*,} if [[ -n $LOCAL_MANAGED_SYSTEM_MTM && -n $LOCAL_MANAGED_SYSTEM_SN ]]; then #======================================================= : Two first characters of SN need to be stripped #======================================================= sys_name=${LOCAL_MANAGED_SYSTEM_MTM}*${LOCAL_MANAGED_SYSTEM_SN:2} fi if [[ -n $sys_name ]]; then clhmcexec "lssyscfg -r sys -m $sys_name -F name" sys_name rc=$? if (( $? != 0 )) ; then rc=$RC_FAILURE fi fi fi (( rc != $RC_SUCCESS )) && sys_name="" # : returning sys_name=$sys_name # return $rc } # End of "get_local_managed_system()" #============================================================================= # # Name: get_enterprise_pool # # Description: Obtain Enterprise Pool name. The name is gotten from the HMC, # or default to null. # # Arguments: $1 [INOUT] epcod_name - reference to the enterprise pool name. # $2 [IN] sys_name - managed system name to search enterprise pool for. # # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_enterprise_pool { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n epcod_name=$1 typeset sys_name=$2 typeset ms_filter="" typeset out_str="" if [[ -z $epcod_name ]] ; then #======================================================= : First, look into ODM if the lpar name corresponds. #======================================================= if [[ $(ODMDIR="/etc/es/objrepos" clodmget -q "key=MANAGED_SYSTEM" -nf value HACMPdynresop 2>/dev/null) == $sys_name ]] ; then epcod_name=$(ODMDIR="/etc/es/objrepos" clodmget -q "key=ENTERPRISE_POOL" -nf value HACMPdynresop 2>/dev/null) rc=$? fi if (( rc == $RC_SUCCESS )) && [[ -z $epcod_name ]] ; then #======================================================= : Then, ask the HMC to check for each enterprise pools : if it contains the managed system. #======================================================= [[ -z $ms_filter && $sys_name == +([a-z]|[A-Z]|[0-9])-+([a-z]|[A-Z]|[0-9])\*+([a-z]|[A-Z]|[0-9]) ]] \ && ms_filter="mtms" [[ -z $ms_filter && -n $sys_name ]] \ && ms_filter="names" if [[ -n $ms_filter ]] ; then clhmcexec "$func_HMCEXEC_managed_system_to_enterprise_pool ; HMCEXEC_managed_system_to_enterprise_pool $ms_filter $sys_name" out_str rc=$? if (( rc == $RC_SUCCESS )) && [[ $out_str != "No results were found." ]] ; then epcod_name=$out_str else epcod_name="" fi fi [[ -z $epcod_name ]] \ && rc=$RC_FAILURE fi fi # : returning epcod_name=$epcod_name # return $rc } # End of "get_enterprise_pool()" #============================================================================= # # Name: get_profile # # Description: Obtain partition profile name. The name is gotten from the HMC, # or default to null. # # Arguments: $1 [INOUT] prof_name - reference to the profile name. # $2 [IN] lpar_name - partition name to search profile for. # $3 [IN] sys_name - managed system name matching lpar name # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_profile { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n prof_name=$1 typeset lpar_name=$2 typeset sys_name=$3 if [[ -z $prof_name ]] ; then #======================================================= : Ask the HMC. #======================================================= clhmcexec "lssyscfg -m $sys_name -r lpar --filter lpar_names=$lpar_name -F curr_profile" prof_name rc=$? if (( rc == $RC_SUCCESS )) && [[ -z $prof_name ]] ; then #======================================================= : Unset and return failure. #======================================================= prof_name="" rc=$RC_FAILURE fi fi # : returning prof_name=$prof_name # return $rc } # End of "get_profile()" #============================================================================= # # Name: get_shared_processor_pool # # Description: Obtain shared processor pool name. The name is gotten from the # HMC, or default to null. # # Arguments: $1 [INOUT] spp_name - reference to the shared processor pool name. # $2 [IN] lpar_name - partition name to search shared processor pool for. # $3 [IN] sys_name - managed system name matching lpar name # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_shared_processor_pool { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n spp_name=$1 typeset lpar_name=$2 typeset sys_name=$3 if [[ -z $spp_name ]] ; then #======================================================= : First, ask the HMC. #======================================================= clhmcexec "lshwres -m $sys_name -r proc --level lpar --filter lpar_names=$lpar_name -F curr_shared_proc_pool_name" spp_name rc=$? if (( rc == $RC_SUCCESS )) && [[ -z $spp_name || $spp_name == "null" ]] ; then #======================================================= : Then, unset and return failure. : The previous command may return null string on : dedicated lpars. #======================================================= spp_name="" rc=$RC_FAILURE fi fi # : returning spp_name=$spp_name # return $rc } # End of "get_shared_processor_pool()" #============================================================================= # # Name: get_lpars_state # # Description: Obtain state of partitions in order to apply different behavior for # several functions. # # Arguments: $1 [IN] sys_name - managed system name on which we parse lpars. # # Globals: g_not_act_lpars_list - List of lpars in state Not Activated. # g_running_lpars_list - List of lpars in any other state. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_lpars_state { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset sys_name=$1 typeset lpar_name= lpar_state= typeset res= g_not_act_lpars_list="" g_running_lpars_list="" clhmcexec "lssyscfg -m $sys_name -r lpar -F name:state" res rc=$? (( rc == $RC_SUCCESS )) && print "$res" | \ while IFS=: read lpar_name lpar_state ; do [[ $lpar_state == "Not Activated" ]] \ && g_not_act_lpars_list="${g_not_act_lpars_list}${g_not_act_lpars_list:+,}${lpar_name}" \ || g_running_lpars_list="${g_running_lpars_list}${g_running_lpars_list:+,}${lpar_name}" done return $rc } #============================================================================= # # Name: get_free_sys_mem # # Description: Obtain available amount of memory by considering shutdowned # partitions, and by considering shared memory pool. # # Arguments: $1 [INOUT] mem_avail - reference to the available memory. # $2 [IN] sys_name - managed system name to search available memory for. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_free_sys_mem { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n mem_avail=$1 typeset sys_name=$2 typeset configurable_sys_mem= sys_firmware_mem= run_mem= curr_mem= typeset lpar_name= lpar_state= typeset curr_pool_mem= typeset res= #======================================================= : Get configurable memory #======================================================= clhmcexec "lshwres -m $sys_name --level sys -r mem -F configurable_sys_mem:sys_firmware_mem" res rc=$? #======================================================= : Substract memory used by other partitions # First separate lpars depending on their state #======================================================= if (( rc == $RC_SUCCESS )) ; then print "$res" | IFS=: read configurable_sys_mem sys_firmware_mem (( mem_avail = configurable_sys_mem - sys_firmware_mem )) [[ -z $g_not_act_lpars_list ]] && [[ -z $g_running_lpars_list ]] \ && get_lpars_state $sys_name fi #======================================================= # For Not Activated ones, consider run_mem #======================================================= if (( rc == $RC_SUCCESS )) && [[ -n $g_not_act_lpars_list ]] ; then clhmcexec "lshwres -m $sys_name -r mem --level lpar --filter \"\\\"lpar_names=$g_not_act_lpars_list\\\"\" -F run_mem" res rc=$? (( rc == $RC_SUCCESS )) && print "$res" | \ while read run_mem ; do (( mem_avail -= run_mem )) done fi #======================================================= # For other ones, consider curr_mem #======================================================= if (( rc == $RC_SUCCESS )) && [[ -n $g_running_lpars_list ]] ; then clhmcexec "lshwres -m $sys_name -r mem --level lpar --filter \"\\\"lpar_names=$g_running_lpars_list\\\"\" -F curr_mem" res rc=$? (( rc == $RC_SUCCESS )) && print "$res" | \ while read curr_mem ; do (( mem_avail -= curr_mem )) done fi #======================================================= : Substract memory used by shared memory pool. #======================================================= if (( rc == $RC_SUCCESS )) ; then clhmcexec "lshwres -m $sys_name -r mempool -F curr_pool_mem" curr_pool_mem rc=$? if (( rc == $RC_SUCCESS )) && [[ $curr_pool_mem != "No results were found." ]] ; then (( mem_avail -= curr_pool_mem )) fi fi #============================================= : Available memory should be a positive value. #============================================= if (( mem_avail < 0.00 )); then mem_avail=0.00 fi return $rc } # End of "get_free_sys_mem()" #============================================================================= # # Name: get_free_sys_proc_units # # Description: Provide computed available processing units by considering # shutdowned partitions, and by considering reserved of shared processor pools. # # Arguments: $1 [INOUT] proc_units_avail - reference to the available processing units. # $2 [IN] sys_name - managed system name to search available processing units for. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_free_sys_proc_units { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n proc_units_avail=$1 typeset sys_name=$2 typeset configurable_sys_proc_units= curr_proc_mode= run_proc_units= curr_proc_units= run_procs= curr_procs= typeset lpar_name= lpar_state= typeset procpool_name= procpool_reserved= typeset res= #======================================================= : Get configurable processing units #======================================================= clhmcexec "lshwres -m $sys_name --level sys -r proc -F configurable_sys_proc_units" configurable_sys_proc_units rc=$? #======================================================= : Substract processing units used by other partition # First separate lpars depending on their state #======================================================= if (( rc == $RC_SUCCESS )) ; then (( proc_units_avail = configurable_sys_proc_units )) [[ -z $g_not_act_lpars_list ]] && [[ -z $g_running_lpars_list ]] \ && get_lpars_state $sys_name fi #======================================================= # For Not Activated ones, consider run_procs #======================================================= if (( rc == $RC_SUCCESS )) && [[ -n $g_not_act_lpars_list ]] ; then clhmcexec "lshwres -m $sys_name -r proc --level lpar --filter \"\\\"lpar_names=$g_not_act_lpars_list\\\"\" -F curr_proc_mode:run_proc_units:run_procs" res rc=$? (( rc == $RC_SUCCESS )) && print "$res" | \ while IFS=: read curr_proc_mode run_proc_units run_procs ; do if [[ $curr_proc_mode == "shared" ]] ; then (( proc_units_avail -= run_proc_units )) elif [[ $curr_proc_mode == "ded" ]] ; then (( proc_units_avail -= run_procs )) fi done fi #======================================================= # For other ones, consider curr_procs #======================================================= if (( rc == $RC_SUCCESS )) && [[ -n $g_running_lpars_list ]] ; then clhmcexec "lshwres -m $sys_name -r proc --level lpar --filter \"\\\"lpar_names=$g_running_lpars_list\\\"\" -F curr_proc_mode:curr_proc_units:curr_procs" res rc=$? (( rc == $RC_SUCCESS )) && print "$res" | \ while IFS=: read curr_proc_mode curr_proc_units curr_procs ; do if [[ $curr_proc_mode == "shared" ]] ; then (( proc_units_avail -= curr_proc_units )) elif [[ $curr_proc_mode == "ded" ]] ; then (( proc_units_avail -= curr_procs )) fi done fi #======================================================= : Substract processing units used by shared pool. Do not : consider DefaultPool which has no reserved. #======================================================= if (( rc == $RC_SUCCESS )) ; then clhmcexec "lshwres -m $sys_name -r procpool -F name:curr_reserved_pool_proc_units" res rc=$? if (( rc == $RC_SUCCESS )) ; then print "$res" | grep -wv DefaultPool | \ while IFS=: read procpool_name procpool_reserved ; do (( proc_units_avail -= procpool_reserved )) done fi fi #========================================= : Available Proc units should be positive. #========================================= if (( proc_units_avail < 0.00 )); then proc_units_avail=0.00 fi return $RC_SUCCESS } # End of "get_free_sys_proc_units()" #============================================================================= # # Name: get_free_pool_proc_units # # Description: Obtain current available processing units in shared processor # pool # # Arguments: $1 [INOUT] proc_units_avail - reference to the available processing units. # $2 [IN] sys_name - managed system name of the shared processor pool. # $3 [IN] procpool_name - shared processor pool name to search available processing units for. # # Returns: RC_SUCCESS # RC_FAILURE # #============================================================================= function get_free_pool_proc_units { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n proc_units_avail=$1 typeset sys_name=$2 typeset procpool_name=$3 typeset -F4 max=0.00 reserved=0.00 curr_proc_units=0.00 typeset lpar_list="" lpar_name="" res="" if [[ $procpool_name != "DefaultPool" ]] ; then #======================================================= : Get attributes for shared processor pool #======================================================= clhmcexec "lshwres -m $sys_name -r procpool --filter pool_names=$procpool_name -F max_pool_proc_units:curr_reserved_pool_proc_units:lpar_names" res rc=$? if (( rc == $RC_SUCCESS )) ; then print "$res" | IFS=: read max reserved lpar_list (( proc_units_avail = max - reserved )) #======================================================= : Substract processing units used by other partitions : in the shared processor pool #======================================================= clhmcexec "lshwres -m $sys_name -r proc --level lpar --filter \"\\\"lpar_names=$lpar_list\\\"\" -F curr_proc_units" res rc=$? (( rc == $RC_SUCCESS )) && print "$res" | \ while read curr_proc_units ; do (( proc_units_avail -= curr_proc_units )) done #========================================= : Available Proc Units should be positive. #========================================= if (( proc_units_avail < 0.00 )); then proc_units_avail=0.00 fi fi else proc_units_avail="unknown" fi return $RC_SUCCESS } # End of "get_free_pool_proc_units()" #============================================================================= # # Name: gather_and_convert # # Description: Gather together attributes that should be executed by the same # HMC command. Also convert attributes to be HMC compatible. # # Arguments: $1 [IN] attrs - space-separated list of attributes. # $2 [INOUT] cmds - reference to the array of attributes for each command. # # Environment: g_convtabHMC78 # # Returns: RC_SUCCESS # #============================================================================= function gather_and_convert { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset attrs=$1 typeset -n cmds=$2 for attr in $attrs ; do case $attr in #======================================================= # 0. local #======================================================= hmc_list|hmc_version|local_sys_name|local_lpar_name|local_prof_name|local_procpool_name|local_codpool_name) # Do nothing here. it will be added to the output list in sort_and_output ;; #======================================================= # 1. cec_sys (lssyscfg -m $g_managed_system -r sys) #======================================================= sys_name|sys_state|sys_type_model|cod_mem_capable|cod_proc_capable) cmds.cec_sys=${cmds.cec_sys:+"${cmds.cec_sys}:"}${g_convtabHMC78[$attr]} ;; sys_lpar_names) # Do nothing here. it will be added to the output list in sort_and_output ;; #======================================================= # 2. cec_mem (lshwres -m $g_managed_system --level sys -r mem) #======================================================= mem_region_size|installed_sys_mem|configurable_sys_mem|sys_firmware_mem|curr_avail_sys_mem|deconfig_sys_mem) cmds.cec_mem=${cmds.cec_mem:+"${cmds.cec_mem}:"}${g_convtabHMC78[$attr]} ;; curr_free_sys_mem) # Do nothing here. it will be added to the output list in sort_and_output ;; #======================================================= # 3. cec_proc (lshwres -m $g_managed_system --level sys -r proc) #======================================================= installed_sys_proc_units|configurable_sys_proc_units|curr_avail_sys_proc_units|min_proc_units_per_virtual_proc|deconfig_sys_proc_units) cmds.cec_proc=${cmds.cec_proc:+"${cmds.cec_proc}:"}${g_convtabHMC78[$attr]} ;; curr_free_sys_proc_units) # Do nothing here. it will be added to the output list in sort_and_output ;; #======================================================= # 4. lpar_sys (lssyscfg -m $g_managed_system -r lpar --filter lpar_names=$g_partition) #======================================================= lpar_name|lpar_id|uuid|lpar_state|curr_profile|lpar_avail_priority) cmds.lpar_sys=${cmds.lpar_sys:+"${cmds.lpar_sys}:"}${g_convtabHMC78[$attr]} ;; #======================================================= # 5. lpar_prof (lssyscfg -m $g_managed_system -r prof --filter profile_names=$g_profile,lpar_names=$g_partition) #======================================================= prof_name|prof_proc_mode|prof_sharing_mode|prof_shared_procpool|prof_minimum_mem|prof_minimum_procs|prof_minimum_proc_units|prof_desired_mem|prof_desired_procs|prof_desired_proc_units|prof_maximum_mem|prof_maximum_procs|prof_maximum_proc_units) cmds.lpar_prof=${cmds.lpar_prof:+"${cmds.lpar_prof}:"}${g_convtabHMC78[$attr]} ;; #======================================================= # 6. lpar_mem (lshwres -m $g_managed_system -r mem --level lpar --filter lpar_names=$g_partition) #======================================================= curr_min_mem|curr_mem|curr_max_mem) cmds.lpar_mem=${cmds.lpar_mem:+"${cmds.lpar_mem}:"}${g_convtabHMC78[$attr]} ;; #======================================================= # 7. lpar_proc (lshwres -m $g_managed_system -r proc --level lpar --filter lpar_names=$g_partition) #======================================================= curr_proc_mode|curr_min_procs|curr_procs|curr_max_procs|curr_min_proc_units|curr_proc_units|curr_max_proc_units) cmds.lpar_proc=${cmds.lpar_proc:+"${cmds.lpar_proc}:"}${g_convtabHMC78[$attr]} ;; #======================================================= # 8. lpar_procpool (lshwres -m $g_managed_system -r procpool --filter pool_names=$g_shared_proc_pool) #======================================================= procpool_name|max_pool_proc_units|curr_reserved_pool_proc_units) cmds.lpar_procpool=${cmds.lpar_procpool:+"${cmds.lpar_procpool}:"}${g_convtabHMC78[$attr]} ;; curr_free_pool_proc_units) # Do nothing here. it will be added to the output list in sort_and_output ;; #======================================================= # 9. trial_mem (lscod -t cap -m $g_managed_system -c trial -r mem) #======================================================= mem_trial_state|activated_trial_mem|mem_trial_days_left|mem_trial_hours_left) cmds.trial_mem=${cmds.trial_mem:+"${cmds.trial_mem}:"}${g_convtabHMC78[$attr]} ;; #======================================================= # 10. trial_proc (lscod -t cap -m $g_managed_system -c trial -r proc) #======================================================= proc_trial_state|activated_trial_procs|proc_trial_days_left|proc_trial_hours_left) cmds.trial_proc=${cmds.trial_proc:+"${cmds.trial_proc}:"}${g_convtabHMC78[$attr]} ;; #======================================================= # 11. onoff_mem (lscod -t cap -m $g_managed_system -c onoff -r mem) #======================================================= mem_onoff_state|activated_onoff_mem|avail_mem_for_onoff|unreturned_onoff_mem|onoff_request_mem_days_left|onoff_mem_day_hours_left|onoff_mem_days_avail) cmds.onoff_mem=${cmds.onoff_mem:+"${cmds.onoff_mem}:"}${g_convtabHMC78[$attr]} ;; #======================================================= # 12. onoff_proc (lscod -t cap -m $g_managed_system -c onoff -r proc) #======================================================= proc_onoff_state|activated_onoff_procs|avail_procs_for_onoff|unreturned_onoff_procs|onoff_request_proc_days_left|onoff_proc_day_hours_left|onoff_proc_days_avail) cmds.onoff_proc=${cmds.onoff_proc:+"${cmds.onoff_proc}:"}${g_convtabHMC78[$attr]} ;; #======================================================= # 13. epcod_pool (lscodpool -p $g_enterprise_pool --level pool) #======================================================= codpool_name|mobile_state|master_mc_name|backup_master_mc_name|mobile_mem|avail_mobile_mem|unreturned_mobile_mem|mobile_procs|avail_mobile_procs|unreturned_mobile_procs) cmds.epcod_pool=${cmds.epcod_pool:+"${cmds.epcod_pool}:"}${g_convtabHMC78[$attr]} ;; #======================================================= # 14. epcod_sys (lscodpool -p $g_enterprise_pool --level sys --filter names=$g_managed_system) #======================================================= sys_mobile_mem|sys_unreturned_mobile_mem|sys_inactive_mem|sys_mobile_procs|sys_unreturned_mobile_procs|sys_inactive_procs) cmds.epcod_sys=${cmds.epcod_sys:+"${cmds.epcod_sys}:"}${g_convtabHMC78[$attr]} ;; codpool_sys_names) # Do nothing here. it will be added to the output list in sort_and_output ;; #======================================================= # 15. lpar_cspp (lshwres -m $g_managed_system -r proc --level lpar --filter lpar_names=$g_partition) #======================================================= curr_shared_proc_pool_name) cmds.lpar_cspp=${cmds.lpar_cspp:+"${cmds.lpar_cspp}:"}${g_convtabHMC78[$attr]} ;; esac done return $RC_SUCCESS } # End of "gather_and_convert()" #============================================================================= # # Name: execute_query_cmds # # Description: Execute sequentially at most 14 HMC commands, if needed among # 'lssyscfg', 'lshwres', 'lscod', and 'lscodpool'. If the command # can not be issued or returns an error, the corresponding # attributes are default to null and the function succeeds. # # Arguments: $1 [IN] cmds - reference to the array of attributes for each command. # $2 [INOUT] res - reference to the array of results for each command. # # Environment: g_partition # g_managed_system # g_profile # g_shared_proc_pool # g_enterprise_pool # # Returns: RC_SUCCESS # #============================================================================= function execute_query_cmds { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n cmd=$1 typeset -n res=$2 typeset attrs_list= list_out= #======================================================= # This function sets all fields from input to unknown. # It has to be defined as func() to allow compound # variable res.xxx to be known inside this embedded # function, or else a 'no parent' error will occur. #======================================================= fill_with_unknown() { typeset -n out=$2 for attr in ${1//:/ } ; do out=${out:+"$out:"}"unknown" done } # End of "fill_with_unknown()" #======================================================= # 1. cec_sys #======================================================= if [[ -n ${cmd.cec_sys} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_managed_system ]] ; then fill_with_unknown ${cmd.cec_sys} res.cec_sys else clhmcexec "lssyscfg -m $g_managed_system -r sys -F ${cmd.cec_sys}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.cec_sys} res.cec_sys else res.cec_sys=$list_out fi fi fi #======================================================= # 2. cec_mem #======================================================= if [[ -n ${cmd.cec_mem} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_managed_system ]] ; then fill_with_unknown ${cmd.cec_mem} res.cec_mem else clhmcexec "lshwres -m $g_managed_system --level sys -r mem -F ${cmd.cec_mem}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.cec_mem} res.cec_mem else res.cec_mem=$list_out fi fi fi #======================================================= # 3. cec_proc #======================================================= if [[ -n ${cmd.cec_proc} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_managed_system ]] ; then fill_with_unknown ${cmd.cec_proc} res.cec_proc else clhmcexec "lshwres -m $g_managed_system --level sys -r proc -F ${cmd.cec_proc}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.cec_proc} res.cec_proc else res.cec_proc=$list_out fi fi fi #======================================================= # 4. lpar_sys #======================================================= if [[ -n ${cmd.lpar_sys} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_partition || -z $g_managed_system ]] ; then fill_with_unknown ${cmd.lpar_sys} res.lpar_sys else clhmcexec "lssyscfg -m $g_managed_system -r lpar --filter lpar_names=$g_partition -F ${cmd.lpar_sys}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.lpar_sys} res.lpar_sys else res.lpar_sys=$list_out fi fi fi #======================================================= # 5. lpar_prof #======================================================= if [[ -n ${cmd.lpar_prof} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition [[ -z $g_profile ]] && get_profile g_profile $g_partition $g_managed_system if [[ -z $g_partition || -z $g_managed_system || -z $g_profile ]] ; then fill_with_unknown ${cmd.lpar_prof} res.lpar_prof else clhmcexec "lssyscfg -m $g_managed_system -r prof --filter profile_names=$g_profile,lpar_names=$g_partition -F ${cmd.lpar_prof}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.lpar_prof} res.lpar_prof else res.lpar_prof=$list_out fi fi fi #======================================================= # 6. lpar_mem #======================================================= if [[ -n ${cmd.lpar_mem} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_partition || -z $g_managed_system ]] ; then fill_with_unknown ${cmd.lpar_mem} res.lpar_mem else clhmcexec "lshwres -m $g_managed_system -r mem --level lpar --filter lpar_names=$g_partition -F ${cmd.lpar_mem}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.lpar_mem} res.lpar_mem else res.lpar_mem=$list_out fi fi fi #======================================================= # 7. lpar_proc #======================================================= if [[ -n ${cmd.lpar_proc} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_partition || -z $g_managed_system ]] ; then fill_with_unknown ${cmd.lpar_proc} res.lpar_proc else clhmcexec "lshwres -m $g_managed_system -r proc --level lpar --filter lpar_names=$g_partition -F ${cmd.lpar_proc}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.lpar_proc} res.lpar_proc else res.lpar_proc=$list_out fi fi fi #======================================================= # 8. lpar_procpool #======================================================= if [[ -n ${cmd.lpar_procpool} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition [[ -z $g_shared_proc_pool ]] && get_shared_processor_pool g_shared_proc_pool $g_partition $g_managed_system if [[ -z $g_managed_system || -z $g_shared_proc_pool ]] ; then fill_with_unknown ${cmd.lpar_procpool} res.lpar_procpool else clhmcexec "lshwres -m $g_managed_system -r procpool --filter pool_names=$g_shared_proc_pool -F ${cmd.lpar_procpool}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.lpar_procpool} res.lpar_procpool else res.lpar_procpool=$list_out fi fi fi #======================================================= # 9. trial_mem #======================================================= if [[ -n ${cmd.trial_mem} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_managed_system ]] ; then fill_with_unknown ${cmd.trial_mem} res.trial_mem else clhmcexec "lscod -t cap -m $g_managed_system -c trial -r mem -F ${cmd.trial_mem}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.trial_mem} res.trial_mem else res.trial_mem=$list_out fi fi fi #======================================================= # 10. trial_proc #======================================================= if [[ -n ${cmd.trial_proc} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_managed_system ]] ; then fill_with_unknown ${cmd.trial_proc} res.trial_proc else clhmcexec "lscod -t cap -m $g_managed_system -c trial -r proc -F ${cmd.trial_proc}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.trial_proc} res.trial_proc else res.trial_proc=$list_out fi fi fi #======================================================= # 11. onoff_mem #======================================================= if [[ -n ${cmd.onoff_mem} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_managed_system ]] ; then fill_with_unknown ${cmd.onoff_mem} res.onoff_mem else clhmcexec "lscod -t cap -m $g_managed_system -c onoff -r mem -F ${cmd.onoff_mem}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.onoff_mem} res.onoff_mem else res.onoff_mem=$list_out fi fi fi #======================================================= # 12. onoff_proc #======================================================= if [[ -n ${cmd.onoff_proc} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_managed_system ]] ; then fill_with_unknown ${cmd.onoff_proc} res.onoff_proc else clhmcexec "lscod -t cap -m $g_managed_system -c onoff -r proc -F ${cmd.onoff_proc}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.onoff_proc} res.onoff_proc else res.onoff_proc=$list_out fi fi fi #======================================================= # 13. epcod_pool #======================================================= if [[ -n ${cmd.epcod_pool} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition [[ -z $g_enterprise_pool ]] && get_enterprise_pool g_enterprise_pool $g_managed_system if [[ -z $g_enterprise_pool ]] ; then fill_with_unknown ${cmd.epcod_pool} res.epcod_pool else #======================================================= # Query operation on ENterprise Pool does not care # about Master HMC. #======================================================= g_epcod_modify_operation=0 if [[ ${cmd.epcod_pool} == "name" ]] ; then list_out=$g_enterprise_pool rc=$RC_SUCCESS else clhmcexec "lscodpool -p $g_enterprise_pool --level pool -F ${cmd.epcod_pool}" list_out rc=$? fi if (( rc != $RC_SUCCESS )) ; then fill_with_unknown ${cmd.epcod_pool} res.epcod_pool else res.epcod_pool=$list_out fi fi fi #======================================================= # 14. epcod_sys #======================================================= if [[ -n ${cmd.epcod_sys} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition [[ -z $g_enterprise_pool ]] && get_enterprise_pool g_enterprise_pool $g_managed_system if [[ -z $g_enterprise_pool ]] ; then fill_with_unknown ${cmd.epcod_sys} res.epcod_sys else #======================================================= # Query operation on Enterprise Pool does not care # about Master HMC. #======================================================= g_epcod_modify_operation=0 clhmcexec "lscodpool -p $g_enterprise_pool --level sys --filter names=$g_managed_system -F ${cmd.epcod_sys}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.epcod_sys} res.epcod_sys else res.epcod_sys=$list_out fi fi fi #======================================================= # 15. lpar_cspp #======================================================= # Retrieving shared processor pool inforation. Though it can be queried with LPAR attributes, # but you may get incorrect data for all the process related attributes when shared processor # pool capability is not enabled. if [[ -n ${cmd.lpar_cspp} ]] ; then [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -z $g_partition || -z $g_managed_system ]] ; then fill_with_unknown ${cmd.lpar_cspp} res.lpar_cspp else clhmcexec "lshwres -m $g_managed_system -r proc --level lpar --filter lpar_names=$g_partition -F ${cmd.lpar_cspp}" list_out rc=$? if (( rc > 0 )) ; then fill_with_unknown ${cmd.lpar_cspp} res.lpar_cspp else res.lpar_cspp=$list_out fi fi fi return $RC_SUCCESS } # End of "execute_query_cmds()" #============================================================================= # # Name: sort_and_output # # Description: Sort results from hmc commands to match input order of # attributes. # # Arguments: $1 [IN] res - reference to the array of results for each command. # $2 [IN] list_in - space-separated list of attributes. # $3 [INOUT] list_out - colon-separated list of value for each attributes. # # Environment: g_partition # g_managed_system # g_local_partition # g_local_managed_system # g_local_profile # g_local_shared_processor_pool # g_local_enterprise_pool # # Returns: RC_SUCCESS # #============================================================================= function sort_and_output { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n res=$1 typeset list_in=$2 typeset -n list_out=$3 typeset -i cec_sys_idx=0 typeset -i cec_mem_idx=0 typeset -i cec_proc_idx=0 typeset -i lpar_sys_idx=0 typeset -i lpar_prof_idx=0 typeset -i lpar_mem_idx=0 typeset -i lpar_proc_idx=0 typeset -i lpar_proc_idx2=0 typeset -i lpar_procpool_idx=0 typeset -i trial_mem_idx=0 typeset -i trial_proc_idx=0 typeset -i onoff_mem_idx=0 typeset -i onoff_proc_idx=0 typeset -i epcod_pool_idx=0 typeset -i epcod_sys_idx=0 for attr in $list_in ; do case $attr in #======================================================= # 0. local #======================================================= hmc_list) if [[ -n $g_hmc_list ]] ; then hmc_list=$g_hmc_list else hmc_list=$(cl_get_hmc_list) fi list_out=${list_out:+"$list_out:"}${hmc_list:-unknown} ;; hmc_version) clhmcexec "lshmc -v" hmc_version hmc_version=$(print "$hmc_version" | sed -n 's/.*\*RM \([^ ]\)/\1/p') list_out=${list_out:+"$list_out:"}${hmc_version:-unknown} ;; local_sys_name) [[ -z $g_local_partition ]] && get_local_partition g_local_partition [[ -z $g_local_managed_system ]] && get_managed_system g_local_managed_system $g_local_partition list_out=${list_out:+"$list_out:"}${g_local_managed_system:-unknown} ;; local_lpar_name) [[ -z $g_local_partition ]] && get_local_partition g_local_partition list_out=${list_out:+"$list_out:"}${g_local_partition:-unknown} ;; local_prof_name) [[ -z $g_local_partition ]] && get_local_partition g_local_partition [[ -z $g_local_managed_system ]] && get_managed_system g_local_managed_system $g_local_partition [[ -z $g_local_profile ]] && get_profile g_local_profile $g_local_partition $g_local_managed_system list_out=${list_out:+"$list_out:"}${g_local_profile:-unknown} ;; local_procpool_name) [[ -z $g_local_partition ]] && get_local_partition g_local_partition [[ -z $g_local_managed_system ]] && get_managed_system g_local_managed_system $g_local_partition [[ -z $g_local_shared_processor_pool ]] && get_shared_processor_pool g_local_shared_processor_pool $g_local_partition $g_local_managed_system list_out=${list_out:+"$list_out:"}${g_local_shared_processor_pool:-unknown} ;; local_codpool_name) [[ -z $g_local_partition ]] && get_local_partition g_local_partition [[ -z $g_local_managed_system ]] && get_managed_system g_local_managed_system $g_local_partition [[ -z $g_local_enterprise_pool ]] && get_enterprise_pool g_local_enterprise_pool $g_local_managed_system list_out=${list_out:+"$list_out:"}${g_local_enterprise_pool:-unknown} ;; #======================================================= # 1. cec_sys (lssyscfg -m $g_managed_system -r sys) #======================================================= sys_name|sys_state|sys_type_model|cod_mem_capable|cod_proc_capable) print "${res.cec_sys}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$cec_sys_idx]} (( cec_sys_idx += 1 )) ;; sys_lpar_names) [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -n $g_managed_system ]] ; then clhmcexec "lssyscfg -m $g_managed_system -r lpar -F name" sys_lpar_names fi sys_lpar_names=$(print $sys_lpar_names|wc -w) list_out=${list_out:+"$list_out:"}${sys_lpar_names:-unknown} ;; #======================================================= # 2. cec_mem (lshwres -m $g_managed_system --level sys -r mem) #======================================================= mem_region_size|installed_sys_mem|configurable_sys_mem|sys_firmware_mem|curr_avail_sys_mem|deconfig_sys_mem) print "${res.cec_mem}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$cec_mem_idx]} (( cec_mem_idx += 1 )) ;; curr_free_sys_mem) [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -n $g_managed_system ]] ; then get_free_sys_mem value $g_managed_system fi list_out=${list_out:+"$list_out:"}${value:-unknown} ;; #======================================================= # 3. cec_proc (lshwres -m $g_managed_system --level sys -r proc) #======================================================= installed_sys_proc_units|configurable_sys_proc_units|curr_avail_sys_proc_units|min_proc_units_per_virtual_proc|deconfig_sys_proc_units) print "${res.cec_proc}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$cec_proc_idx]} (( cec_proc_idx += 1 )) ;; curr_free_sys_proc_units) [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -n $g_managed_system ]] ; then get_free_sys_proc_units value $g_managed_system fi list_out=${list_out:+"$list_out:"}${value:-unknown} ;; #======================================================= # 4. lpar_sys (lssyscfg -m $g_managed_system -r lpar --filter lpar_names=$g_partition) #======================================================= lpar_name|lpar_id|uuid|lpar_state|curr_profile|lpar_avail_priority) print "${res.lpar_sys}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$lpar_sys_idx]} (( lpar_sys_idx += 1 )) ;; #======================================================= # 5. lpar_prof (lssyscfg -m $g_managed_system -r prof --filter profile_names=$g_profile,lpar_names=$g_partition) #======================================================= prof_name|prof_proc_mode|prof_sharing_mode|prof_shared_procpool|prof_minimum_mem|prof_minimum_procs|prof_minimum_proc_units|prof_desired_mem|prof_desired_procs|prof_desired_proc_units|prof_maximum_mem|prof_maximum_procs|prof_maximum_proc_units) print "${res.lpar_prof}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$lpar_prof_idx]} (( lpar_prof_idx += 1 )) ;; #======================================================= # 6. lpar_mem (lshwres -m $g_managed_system -r mem --level lpar --filter lpar_names=$g_partition) #======================================================= curr_min_mem|curr_mem|curr_max_mem) print "${res.lpar_mem}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$lpar_mem_idx]} (( lpar_mem_idx += 1 )) ;; #======================================================= # 7. lpar_proc (lshwres -m $g_managed_system -r proc --level lpar --filter lpar_names=$g_partition) #======================================================= curr_proc_mode|curr_min_procs|curr_procs|curr_max_procs|curr_min_proc_units|curr_proc_units|curr_max_proc_units) print "${res.lpar_proc}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$lpar_proc_idx]} (( lpar_proc_idx += 1 )) ;; #======================================================= # 8. lpar_procpool (lshwres -m $g_managed_system -r procpool --filter pool_names=$g_shared_proc_pool) #======================================================= procpool_name|max_pool_proc_units|curr_reserved_pool_proc_units) print "${res.lpar_procpool}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$lpar_procpool_idx]} (( lpar_procpool_idx += 1 )) ;; curr_free_pool_proc_units) [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition [[ -z $g_shared_proc_pool ]] && get_shared_processor_pool g_shared_proc_pool $g_partition $g_managed_system if [[ -n $g_managed_system && -n $g_shared_proc_pool ]] ; then get_free_pool_proc_units value $g_managed_system $g_shared_proc_pool fi list_out=${list_out:+"$list_out:"}${value:-unknown} ;; #======================================================= # 9. trial_mem (lscod -t cap -m $g_managed_system -c trial -r mem) #======================================================= mem_trial_state|activated_trial_mem|mem_trial_days_left|mem_trial_hours_left) print "${res.trial_mem}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$trial_mem_idx]} (( trial_mem_idx += 1 )) ;; #======================================================= # 10. trial_proc (lscod -t cap -m $g_managed_system -c trial -r proc) #======================================================= proc_trial_state|activated_trial_procs|proc_trial_days_left|proc_trial_hours_left) print "${res.trial_proc}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$trial_proc_idx]} (( trial_proc_idx += 1 )) ;; #======================================================= # 11. onoff_mem (lscod -t cap -m $g_managed_system -c onoff -r mem) #======================================================= mem_onoff_state|activated_onoff_mem|avail_mem_for_onoff|unreturned_onoff_mem|onoff_request_mem_days_left|onoff_mem_day_hours_left|onoff_mem_days_avail) print "${res.onoff_mem}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$onoff_mem_idx]} (( onoff_mem_idx += 1 )) ;; #======================================================= # 12. onoff_proc (lscod -t cap -m $g_managed_system -c onoff -r proc) #======================================================= proc_onoff_state|activated_onoff_procs|avail_procs_for_onoff|unreturned_onoff_procs|onoff_request_proc_days_left|onoff_proc_day_hours_left|onoff_proc_days_avail) print "${res.onoff_proc}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$onoff_proc_idx]} (( onoff_proc_idx += 1 )) ;; #======================================================= # 13. epcod_pool (lscodpool -p $g_enterprise_pool --level pool) #======================================================= codpool_name|mobile_state|master_mc_name|backup_master_mc_name|mobile_mem|avail_mobile_mem|unreturned_mobile_mem|mobile_procs|avail_mobile_procs|unreturned_mobile_procs) print "${res.epcod_pool}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$epcod_pool_idx]} (( epcod_pool_idx += 1 )) ;; #======================================================= # 14. epcod_sys (lscodpool -p $g_enterprise_pool --level sys --filter names=$g_managed_system) #======================================================= sys_mobile_mem|sys_unreturned_mobile_mem|sys_inactive_mem|sys_mobile_procs|sys_unreturned_mobile_procs|sys_inactive_procs) print "${res.epcod_sys}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$epcod_sys_idx]} (( epcod_sys_idx += 1 )) ;; codpool_sys_names) [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition [[ -z $g_enterprise_pool ]] && get_enterprise_pool g_enterprise_pool $g_managed_system if [[ -n $g_enterprise_pool ]] ; then clhmcexec "lscodpool -p $g_enterprise_pool --level sys -F name" codpool_sys_names fi codpool_sys_names=$(print $codpool_sys_names) list_out=${list_out:+"$list_out:"}${codpool_sys_names:-unknown} ;; #======================================================= # 15. lpar_cspp (lshwres -m $g_managed_system -r proc --level lpar --filter lpar_names=$g_partition) #======================================================= curr_shared_proc_pool_name) print "${res.lpar_cspp}" | IFS=: read -A tab list_out=${list_out:+"$list_out:"}${tab[$lpar_proc_idx2]} (( lpar_proc_idx2 += 1 )) ;; esac done return $RC_SUCCESS } # End of "sort_and_output()" #============================================================================= # # Name: process_query # # Description: Process a 'query' operation on some attributes. # # Arguments: None # # Environment: g_attributes # g_labels # # Returns: RC_SUCCESS # #============================================================================= function process_query { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset attr_list=${g_attributes//:/ } typeset lbl_str="" out_str="" if (( g_labels == 1 )) ; then #======================================================= : Display header #======================================================= lbl_str="$g_attributes\n" fi typeset commands=( # colon-separated list of attributes typeset cec_sys typeset cec_mem typeset cec_proc typeset lpar_sys typeset lpar_prof typeset lpar_mem typeset lpar_proc typeset lpar_cspp typeset lpar_procpool typeset trial_mem typeset trial_proc typeset onoff_mem typeset onoff_proc typeset epcod_pool typeset epcod_sys ) typeset results=( # colon-separated list of results typeset cec_sys typeset cec_mem typeset cec_proc typeset lpar_sys typeset lpar_prof typeset lpar_mem typeset lpar_proc typeset lpar_cspp typeset lpar_procpool typeset trial_mem typeset trial_proc typeset onoff_mem typeset onoff_proc typeset epcod_pool typeset epcod_sys ) #======================================================= : First, gather attributes together by HMC commands and : convert them to comprehensible ones. #======================================================= gather_and_convert "$attr_list" commands #======================================================= : Then, execute all commands on HMC and obtain results. #======================================================= execute_query_cmds commands results #======================================================= : Finally, sort results to match attributes order and : format output. #======================================================= sort_and_output results "$attr_list" out_str print -- "${lbl_str}${out_str}" return $RC_SUCCESS } # End of "process_query()" #============================================================================= # # Name: process_change # # Description: Process a 'change' operation on some attributes. # # Arguments: None # # Environment: g_attributes # g_managed_system # g_shared_proc_pool # # Returns: RC_SUCCESS # RC_PARAM_ERROR # or clhmcexec error code if an error occurs. # #============================================================================= function process_change { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -i chg_rc= typeset out_str= print "${g_attributes//:/\\n}" | \ while IFS='=' read key value ; do { case $key in max_pool_proc_units|reserved_pool_proc_units) [[ -z $g_partition ]] && get_local_partition g_partition [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition [[ -z $g_shared_proc_pool ]] && get_shared_processor_pool g_shared_proc_pool $g_partition $g_managed_system if [[ -n $g_shared_proc_pool ]] ; then clhmcexec "chhwres -m $g_managed_system -r procpool --poolname $g_shared_proc_pool -o s -a $key=$value" out_str chg_rc=$? if (( chg_rc > 0 )) ; then rc=$chg_rc fi else dspmsg $ROHA_MSGS -s $ROHA_SET 421 \ "%\1$s: ERROR: %\2$s Shared Processor Pool does not belong to %\3$s LPAR. Provide valid name through -S or -L option.\n" \ "$PROGNAME" "$g_shared_proc_pool" "$g_partition" >&3 rc=$RC_PARAM_ERROR break fi ;; esac } < /dev/null ; done # Avoid ssh to break while loop by redirecting standard input return $rc } # End of "process_change()" #============================================================================= # # Name: process_acquire # # Description: Process an 'acquire' operation of DLPAR, On/Off CoD or # Enterprise Pool CoD memory, processing unit(s) and/or CPU(s) # for the partition. Memory is acquired first, then CPU. # # Arguments: None # # Environment: g_resource # g_memory # g_quantity # g_proc_units # g_force # g_partition # g_managed_system # g_enterprise_pool # # Returns: RC_SUCCESS # RC_PARAM_ERROR # or clhmcexec error code if an error occurs. # #============================================================================= function process_acquire { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset out_str= [[ -z $g_partition ]] && get_local_partition g_partition if [[ -n $g_partition ]] ; then [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -n $g_managed_system ]] ; then case $g_resource in dlpar) g_enable_timeout=1 if (( $g_force == 1 )) ; then #======================================================= : case where g_force = 1 #======================================================= #======================================================= : mem and procs are separately done #======================================================= typeset mem_rc=$RC_UNKNOWN typeset procs_rc=$RC_UNKNOWN #======================================================= : Compute timeout dynamically by adding to the default : timeout, the greatest from memory, processor and : processing units. #======================================================= (( g_timeout += g_memory/1024 > g_proc_units ? $(( g_memory/1024 > g_quantity ? g_memory/1024 : g_quantity )) : g_proc_units )) #======================================================= : Acquire memory. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chhwres -m $g_managed_system -p $g_partition -r mem -o a -q $g_memory" out_str mem_rc=$? if (( $mem_rc == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 537 \ "%1\$s: %2\$d GB of DLPAR resources have been allocated.\n" \ "$PROGNAME" "$mem_gb" else rc=$mem_rc fi fi #======================================================= : Acquire processors. #======================================================= if (( $g_quantity > 0 || $g_proc_units > 0 )) ; then typeset opt_procs= opt_proc_units= (( $g_quantity > 0 )) && opt_procs="--procs $g_quantity" (( $g_proc_units > 0 )) && opt_proc_units="--procunits $g_proc_units" clhmcexec "chhwres -m $g_managed_system -p $g_partition -r proc -o a $opt_procs $opt_proc_units" out_str procs_rc=$? if (( $procs_rc == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 538 \ "%1\$s: %2\$d VP(s) or CPU(s) and %3\$d PU(s) of DLPAR resources have been allocated.\n" \ "$PROGNAME" "$g_quantity" "$g_proc_units" else rc=$procs_rc fi fi #======================================================= # in case of force, and for last loop of reassment, # we do not undo was was potentially done #======================================================= g_enable_timeout=0 return $rc fi # : case where g_force = 0 # #======================================================= : Compute timeout dynamically by adding to the default : timeout, the greatest from memory, processor and : processing units. #======================================================= (( g_timeout += g_memory/1024 > g_proc_units ? $(( g_memory/1024 > g_quantity ? g_memory/1024 : g_quantity )) : g_proc_units )) #======================================================= : Acquire memory. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chhwres -m $g_managed_system -p $g_partition -r mem -o a -q $g_memory" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 537 \ "%1\$s: %2\$d GB of DLPAR resources have been allocated.\n" \ "$PROGNAME" "$mem_gb" fi fi if (( $rc == $RC_SUCCESS )) ; then #======================================================= : Acquire processors. #======================================================= if (( $g_quantity > 0 || $g_proc_units > 0 )) ; then typeset opt_procs= opt_proc_units= (( $g_quantity > 0 )) && opt_procs="--procs $g_quantity" (( $g_proc_units > 0 )) && opt_proc_units="--procunits $g_proc_units" clhmcexec "chhwres -m $g_managed_system -p $g_partition -r proc -o a $opt_procs $opt_proc_units" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 538 \ "%1\$s: %2\$d VP(s) or CPU(s) and %3\$d PU(s) of DLPAR resources have been allocated.\n" \ "$PROGNAME" "$g_quantity" "$g_proc_units" fi fi if (( $rc != $RC_SUCCESS )) ; then #======================================================= : Error while acquiring processors. The operation may : have completed partially. Undo what has been acquired. #======================================================= typeset substr=$out_str substr=${substr##*Amount of processors removed: } substr=${substr%% *} typeset -i cpu=$substr typeset -F4 pu=$substr if (( $cpu > 0 || $pu > 0 )) ; then typeset opt_procs= opt_proc_units= (( $cpu > 0 )) && opt_procs="--procs $cpu" (( $pu > 0 )) && opt_proc_units="--procunits $pu" clhmcexec "chhwres -m $g_managed_system -p $g_partition -r proc -o r $opt_procs $opt_proc_units" out_str if (( $? == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 539 \ "%1\$s: WARNING: allocation of %2\$d VP(s) or CPU(s) and %3\$d PU(s) of DLPAR resources has been undone.\n" \ "$PROGNAME" "$pu" "$vp" >&3 fi fi #======================================================= : Also, despite memory has succeeded, undo what has been : acquired. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chhwres -m $g_managed_system -p $g_partition -r mem -o r -q $g_memory" out_str if (( $? == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 540 \ "%1\$s: WARNING: allocation of %2\$d GB of DLPAR resources has been undone.\n" \ "$PROGNAME" "$mem_gb" >&3 fi fi fi else #======================================================= : Error while acquiring memory. The operation may have : completed partially. Undo what has been acquired. #======================================================= typeset substr=$out_str print $substr | grep -q -i "Attention: Operation completed partially." if (( $? == 0 )) ; then substr=${substr##*Amount of memory added: } substr=${substr%% *} typeset -F4 mem_mb=$substr if (( $mem_mb > 0 )) ; then clhmcexec "chhwres -m $g_managed_system -p $g_partition -r mem -o r -q $mem_mb" out_str if (( $? == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$mem_mb (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 540 \ "%1\$s: WARNING: allocation of %2\$d GB of DLPAR resources has been undone.\n" \ "$PROGNAME" "$mem_gb" >&3 fi fi fi fi g_enable_timeout=0 ;; onoff) if (( $g_force == 1 )) ; then # : mem and procs are separately done # typeset mem_rc=$RC_UNKNOWN typeset procs_rc=$RC_UNKNOWN #======================================================= : Acquire memory. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chcod -m $g_managed_system -r mem -c onoff -o a -q $g_memory -d $g_duration" out_str mem_rc=$? if (( $mem_rc == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 320 \ "%1\$s: %2\$d GB of On/Off CoD resources have been activated for %3\$d days.\n" \ "$PROGNAME" "$mem_gb" "$g_duration" fi fi #======================================================= : Acquire processors. #======================================================= if (( $g_quantity > 0 )) ; then clhmcexec "chcod -m $g_managed_system -r proc -c onoff -o a -q $g_quantity -d $g_duration" out_str procs_rc=$? if (( $procs_rc == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 321 \ "%1\$s: %2\$d CPU(s) of On/Off CoD resources have been activated for %3\$d days.\n" \ "$PROGNAME" "$g_quantity" "$g_duration" fi fi # in case of force, and for last loop of reassment, # we do not undo was was potentially done return $rc fi #======================================================= : Acquire memory. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chcod -m $g_managed_system -r mem -c onoff -o a -q $g_memory -d $g_duration" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 320 \ "%1\$s: %2\$d GB of On/Off CoD resources have been activated for %3\$d days.\n" \ "$PROGNAME" "$mem_gb" "$g_duration" fi fi if (( $rc == $RC_SUCCESS )) ; then #======================================================= : Acquire processors. #======================================================= if (( $g_quantity > 0 )) ; then clhmcexec "chcod -m $g_managed_system -r proc -c onoff -o a -q $g_quantity -d $g_duration" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 321 \ "%1\$s: %2\$d CPU(s) of On/Off CoD resources have been activated for %3\$d days.\n" \ "$PROGNAME" "$g_quantity" "$g_duration" fi fi if (( $rc != $RC_SUCCESS )) ; then #======================================================= : Also, despite memory has succeeded, undo what has been : acquired. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chcod -m $g_managed_system -r mem -c onoff -o d" out_str if (( $? == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 541 \ "%1\$s: WARNING: activation of %2\$d GB of On/Off CoD resources has been undone.\n" \ "$PROGNAME" "$mem_gb" >&3 fi fi fi fi ;; epcod) if (( $g_force == 1 )) ; then # : mem and procs are separately done # [[ -z $g_enterprise_pool ]] && get_enterprise_pool g_enterprise_pool $g_managed_system if [[ -n $g_enterprise_pool ]] ; then g_epcod_modify_operation=1 #======================================================= : Acquire memory. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chcodpool -p $g_enterprise_pool -m $g_managed_system -r mem -o add -q $g_memory" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 542 \ "%1\$s: %2\$d GB of Enterprise Pool CoD have been acquired.\n" \ "$PROGNAME" "$mem_gb" fi fi #======================================================= : Acquire processors. #======================================================= if (( $g_quantity > 0 )) ; then clhmcexec "chcodpool -p $g_enterprise_pool -m $g_managed_system -r proc -o add -q $g_quantity" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 543 \ "%1\$s: %2\$d CPU(s) of Enterprise Pool CoD have been acquired.\n" \ "$PROGNAME" "$g_quantity" fi fi g_epcod_modify_operation=0 # in case of force, and for last loop of reassment, # we do not undo was was potentially done return $rc else dspmsg $ROHA_MSGS -s $ROHA_SET 415 \ "%1\$s: ERROR: unknown %2\$s Enterprise Pool CoD. Provide valid name through -E option.\n" \ "$PROGNAME" "$g_enterprise_pool" >&3 rc=$RC_PARAM_ERROR fi return $rc fi [[ -z $g_enterprise_pool ]] && get_enterprise_pool g_enterprise_pool $g_managed_system if [[ -n $g_enterprise_pool ]] ; then g_epcod_modify_operation=1 #======================================================= : Acquire memory. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chcodpool -p $g_enterprise_pool -m $g_managed_system -r mem -o add -q $g_memory" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 330 \ "%1\$s: %2\$d GB of Enterprise Pool CoD have been acquired.\n" \ "$PROGNAME" "$mem_gb" fi fi if (( $rc == $RC_SUCCESS )) ; then #======================================================= : Acquire processors. #======================================================= if (( $g_quantity > 0 )) ; then clhmcexec "chcodpool -p $g_enterprise_pool -m $g_managed_system -r proc -o add -q $g_quantity" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 331 \ "%1\$s: %2\$d CPU(s) of Enterprise Pool CoD have been acquired.\n" \ "$PROGNAME" "$g_quantity" fi fi if (( $rc != $RC_SUCCESS )) ; then #======================================================= : Also, despite memory has succeeded, undo what has been : acquired. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chcodpool -p $g_enterprise_pool -m $g_managed_system -r mem -o remove -q $g_memory" out_str if (( $? == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 517 \ "%1\$s: WARNING: acquisition of %2\$d GB of Enterprise Pool CoD resources has been undone.\n" \ "$PROGNAME" "$mem_gb" >&3 fi fi fi fi g_epcod_modify_operation=0 else dspmsg $ROHA_MSGS -s $ROHA_SET 415 \ "%1\$s: ERROR: unknown %2\$s Enterprise Pool CoD. Provide valid name through -E option.\n" \ "$PROGNAME" "$g_enterprise_pool" >&3 rc=$RC_PARAM_ERROR fi ;; esac else dspmsg $ROHA_MSGS -s $ROHA_SET 416 \ "%1\$s: ERROR: unknown %2\$s Managed System. Provide valid name through -M option.\n" \ "$PROGNAME" "$g_managed_system" >&3 rc=$RC_PARAM_ERROR fi else dspmsg $ROHA_MSGS -s $ROHA_SET 414 \ "%1\$s: ERROR: unknown %2\$s LPAR. Provide valid name through -L option.\n" \ "$PROGNAME" "$g_partition" >&3 rc=$RC_PARAM_ERROR fi return $rc } # End of "process_acquire()" #============================================================================= # # Name: process_release # # Description: Process a 'release' operation of some DLPAR, On/Off CoD or # Enterprise Pool CoD memory, processing unit(s) and/or CPU(s) # for the partition. # # Arguments: None # # Environment: g_resource # g_memory # g_quantity # g_proc_units # g_force # g_partition # g_managed_system # g_enterprise_pool # # Returns: RC_SUCCESS # RC_PARAM_ERROR # or clhmcexec error code if an error occurs. # #============================================================================= function process_release { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset out_str= typeset proc_out_str= typeset release_order="memory cpu" typeset -i memory_released=0 typeset -i cpu_released=0 # : Release order should be based on the tunable $ROHA_RELEASE_CPU_BEFORE_MEM, : use default one if tunable is not updated # if (( ROHA_RELEASE_CPU_BEFORE_MEM == 1 )); then release_order="cpu memory" fi [[ -z $g_partition ]] && get_local_partition g_partition if [[ -n $g_partition ]] ; then [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -n $g_managed_system ]] ; then case $g_resource in dlpar) g_enable_timeout=1 #======================================================= : Compute timeout dynamically by adding to the default : timeout, the greatest from memory, processor and : processing units. #======================================================= (( g_timeout += ( g_memory/1024 > g_proc_units ) ? $(( ( g_memory/1024 > g_quantity ) ? g_memory/1024 : g_quantity )) : g_proc_units )) for resourceloop in $release_order do case $resourceloop in memory) typeset -i CHUNK_SIZE=10240 #======================================================= : Release memory by chunk of $CHUNK_SIZE MB. #======================================================= if (( $g_memory > 0 )) ; then typeset -i qty=0 tmp=0 while (( qty < g_memory )) ; do tmp=$(( g_memory - qty )) mem_mb=$(( CHUNK_SIZE < tmp ? CHUNK_SIZE : tmp )) clhmcexec "chhwres -m $g_managed_system -p $g_partition -r mem -o r -q $mem_mb" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then (( qty += $mem_mb )) typeset -F4 mem_gb=$qty (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 304 \ "%1\$s: %2\$d GB of DLPAR resources have been released.\n" \ "$PROGNAME" "$mem_gb" elif (( $rc == $RC_REM_RES_BUSY_ERROR )) ; then #======================================================= : Error while releasing memory. The operation may have : completed partially. Also, undo what has been released. #======================================================= typeset substr=$out_str print $substr | grep -q -i "Attention: Operation completed partially." if (( $? == 0 )) ; then substr=${substr##*Amount of memory removed: } substr=${substr%% *} (( qty += $substr )) fi # Continue by releasing CHUNK smaller if (( $CHUNK_SIZE == 10240 )) ; then CHUNK_SIZE=5120 elif (( $CHUNK_SIZE == 5120 )) ; then CHUNK_SIZE=2048 elif (( $CHUNK_SIZE == 2048 )) ; then CHUNK_SIZE=1024 elif (( $CHUNK_SIZE == 1024 )) ; then CHUNK_SIZE=256 else break fi else break fi done fi if (( $rc == $RC_SUCCESS || $g_force == 1 )) ; then #======================================================= : Force return code to success. #======================================================= rc=$RC_SUCCESS memory_released=1 else #======================================================= : Error while releasing memory. Undo what have already : been released. #======================================================= if (( $qty > 0 )) ; then clhmcexec "chhwres -m $g_managed_system -p $g_partition -r mem -o a -q $qty" out_str if (( $? == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$qty (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 511 \ "%1\$s: WARNING: release of %2\$d GB of DLPAR resources has been undone.\n" \ "$PROGNAME" "$mem_gb" >&3 fi fi if (( $cpu_released == 1 )); then #======================================================= : Also, despite CPU has succeeded, undo what has been : released. #======================================================= typeset substr=$proc_out_str substr=${substr##*Amount of processors removed: } substr=${substr%% *} typeset -i cpu=$substr typeset -F4 pu=$substr if (( $cpu > 0 || $pu > 0 )) ; then typeset opt_procs= opt_proc_units= (( $cpu > 0 )) && opt_procs="--procs $cpu" (( $pu > 0 )) && opt_proc_units="--procunits $pu" clhmcexec "chhwres -m $g_managed_system -p $g_partition -r proc -o a $opt_procs $opt_proc_units" out_str if (( $? == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 512 \ "%1\$s: WARNING: release of %2\$d VP(s) or CPU(s) and %3\$d PU(s) of DLPAR resources has been undone.\n" \ "$PROGNAME" "$pu" "$vp" >&3 fi fi fi # come out of case and for loop to avoid processing further break fi ;; cpu) #======================================================= : Release processors. #======================================================= if (( $g_quantity > 0 || $g_proc_units > 0 )) ; then typeset opt_procs= opt_proc_units= (( $g_quantity > 0 )) && opt_procs="--procs $g_quantity" (( $g_proc_units > 0 )) && opt_proc_units="--procunits $g_proc_units" clhmcexec "chhwres -m $g_managed_system -p $g_partition -r proc -o r $opt_procs $opt_proc_units" proc_out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 306 \ "%1\$s: %2\$d VP(s) or CPU(s) and %3\$d PU(s) of DLPAR resources have been released.\n" \ "$PROGNAME" "$g_quantity" "$g_proc_units" fi fi if (( $rc == $RC_SUCCESS || $g_force == 1 )) ; then #======================================================= : Force return code to success. #======================================================= rc=$RC_SUCCESS cpu_released=1 else #======================================================= : Error while releasing processors. The operation may : have completed partially. Undo what has been released. #======================================================= typeset substr=$proc_out_str substr=${substr##*Amount of processors removed: } substr=${substr%% *} typeset -i cpu=$substr typeset -F4 pu=$substr if (( $cpu > 0 || $pu > 0 )) ; then typeset opt_procs= opt_proc_units= (( $cpu > 0 )) && opt_procs="--procs $cpu" (( $pu > 0 )) && opt_proc_units="--procunits $pu" clhmcexec "chhwres -m $g_managed_system -p $g_partition -r proc -o a $opt_procs $opt_proc_units" out_str if (( $? == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 512 \ "%1\$s: WARNING: release of %2\$d VP(s) or CPU(s) and %3\$d PU(s) of DLPAR resources has been undone.\n" \ "$PROGNAME" "$pu" "$vp" >&3 fi fi #======================================================= : Also, despite memory has succeeded, undo what has been : released. #======================================================= if (( $g_memory > 0 && $memory_released == 1)) ; then clhmcexec "chhwres -m $g_managed_system -p $g_partition -r mem -o a -q $g_memory" out_str if (( $? == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 511 \ "%1\$s: WARNING: release of %2\$d GB of DLPAR resources has been undone.\n" \ "$PROGNAME" "$mem_gb" >&3 fi fi # come out of case and for loop to avoid processing further break fi ;; esac done g_enable_timeout=0 ;; onoff) for resourceloop in $release_order do case $resourceloop in memory) #======================================================= : Release memory. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chcod -m $g_managed_system -r mem -c onoff -o d" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 322 \ "%1\$s: All %2\$d GB of On/Off CoD resources have been released.\n" \ "$PROGNAME" "$mem_gb" fi fi if (( $rc == $RC_SUCCESS || $g_force == 1 )) ; then #======================================================= : Force return code to success. #======================================================= memory_released=1 rc=$RC_SUCCESS else # come out of case and for loop to avoid processing further break fi ;; cpu) #======================================================= : Release processors. #======================================================= if (( $g_quantity > 0 )) ; then clhmcexec "chcod -m $g_managed_system -r proc -c onoff -o d" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 323 \ "%1\$s: All %2\$d CPU(s) of On/Off CoD resources have been released.\n" \ "$PROGNAME" "$g_quantity" fi fi if (( $rc == $RC_SUCCESS || $g_force == 1 )) ; then #======================================================= : Force return code to success. #======================================================= rc=$RC_SUCCESS cpu_released=1 else if (( $memory_released == 1)) ; then #======================================================= : Also, despite memory has succeeded, undo what has been : released. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chcod -m $g_managed_system -r mem -c onoff -o a -d $g_duration" out_str if (( $? == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 515 \ "%1\$s: WARNING: release of %2\$d GB of On/Off CoD resources has been undone.\n" \ "$PROGNAME" "$mem_gb" >&3 fi fi fi # come out of case and for loop to avoid processing further break fi ;; esac done ;; epcod) [[ -z $g_enterprise_pool ]] && get_enterprise_pool g_enterprise_pool $g_managed_system if [[ -n $g_enterprise_pool ]] ; then g_epcod_modify_operation=1 for resourceloop in $release_order do case $resourceloop in memory) #======================================================= : Release memory. #======================================================= while (( $g_memory > 0 )); do typeset -i mem_quantity=0 clhmcexec "chcodpool -p $g_enterprise_pool -m $g_managed_system -r mem -o remove -q $g_memory --force" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 332 \ "%1\$s: %2\$d GB of Enterprise Pool CoD have been returned.\n" \ "$PROGNAME" "$mem_gb" elif [[ -n $(echo $out_str | grep "to remove cannot exceed") ]]; then typeset substr=$out_str substr=${out_str% GB*} mem_quantity=${substr##*[!0-9]} #======================================================================== : The amount of mobile memory to be released cannot exceed $mem_quantity #======================================================================== (( mem_quantity *= 1024 )) if (( $mem_quantity > 0 )); then #======================================================== : Resetting mobile memory to be released to $mem_quantity #======================================================== g_memory=$mem_quantity continue else #=================================================== : No mobile memory currently assigned to this server #=================================================== rc=$RC_SUCCESS fi fi #================================ : Nothing to do break from loop #================================ break done if (( $rc == $RC_SUCCESS || $g_force == 1 )) ; then #======================================================= : Force return code to success. #======================================================= rc=$RC_SUCCESS memory_released=1 else # come out of case and for loop to avoid processing further break fi ;; cpu) #======================================================= : Release processors. #======================================================= while (( $g_quantity > 0 )); do typeset -i proc_quantity=0 clhmcexec "chcodpool -p $g_enterprise_pool -m $g_managed_system -r proc -o remove -q $g_quantity --force" out_str rc=$? if (( $rc == $RC_SUCCESS )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 333 \ "%1\$s: %2\$d CPU(s) of Enterprise Pool CoD have been returned.\n" \ "$PROGNAME" "$g_quantity" elif [[ -n $(echo $out_str | grep "to remove cannot exceed") ]]; then typeset substr=$out_str substr=${out_str%,*} proc_quantity=${substr##*[!0-9]} #====================================================================== : The amount of mobile proc to be released cannot exceed $proc_quantity #====================================================================== if (( $proc_quantity > 0 )); then #========================================================= : Resetting mobile procs to be released to $proc_quantity #========================================================= g_quantity=$proc_quantity continue else #================================================================ : No mobile procs currently assigned to this server #================================================================ rc=$RC_SUCCESS fi fi #================================ : Nothing to do break from loop #================================ break done if (( $rc == $RC_SUCCESS || $g_force == 1 )) ; then #======================================================= : Force return code to success. #======================================================= rc=$RC_SUCCESS cpu_released=1 else if (( $memory_released == 1 )) ; then #======================================================= : Also, despite memory has succeeded, undo what has been : released. #======================================================= if (( $g_memory > 0 )) ; then clhmcexec "chcodpool -p $g_enterprise_pool -m $g_managed_system -r mem -o add -q $g_memory" out_str if (( $? == $RC_SUCCESS )) ; then typeset -F4 mem_gb=$g_memory (( mem_gb /= 1024 )) dspmsg $ROHA_MSGS -s $ROHA_SET 519 \ "%1\$s: WARNING: release of %2\$d GB of Enterprise Pool CoD resources has been undone.\n" \ "$PROGNAME" "$mem_gb" >&3 fi fi fi # come out of case and for loop to avoid processing further break fi ;; esac done g_epcod_modify_operation=0 else dspmsg $ROHA_MSGS -s $ROHA_SET 415 \ "%1\$s: ERROR: unknown %2\$s Enterprise Pool CoD. Provide valid name through -E option.\n" \ "$PROGNAME" "$g_enterprise_pool" >&3 rc=$RC_PARAM_ERROR fi ;; esac else dspmsg $ROHA_MSGS -s $ROHA_SET 416 \ "%1\$s: ERROR: unknown %2\$s Managed System. Provide valid name through -M option.\n" \ "$PROGNAME" "$g_managed_system" >&3 rc=$RC_PARAM_ERROR fi else dspmsg $ROHA_MSGS -s $ROHA_SET 414 \ "%1\$s: ERROR: unknown %2\$s LPAR. Provide valid name through -L option.\n" \ "$PROGNAME" "$g_partition" >&3 rc=$RC_PARAM_ERROR fi return $rc } # End of "process_release()" #============================================================================= # # Name: process_halt # # Description: Process a 'halt' operation for the partition. # # Arguments: None # # Environment: g_partition # g_managed_system # # Returns: RC_SUCCESS # RC_PARAM_ERROR # or clhmcexec error code if an error occurs. # #============================================================================= function process_halt { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset out_str= [[ -z $g_partition ]] && get_local_partition g_partition if [[ -n $g_partition ]] ; then [[ -z $g_managed_system ]] && get_managed_system g_managed_system $g_partition if [[ -n $g_managed_system ]] ; then clhmcexec "chsysstate -m $g_managed_system -r lpar -o shutdown --immed -n $g_partition" out_str rc=$? else dspmsg $ROHA_MSGS -s $ROHA_SET 416 \ "%1\$s: ERROR: unknown %2\$s Managed System. Provide valid name through -M option.\n" \ "$PROGNAME" "$g_managed_system" >&3 rc=$RC_PARAM_ERROR fi else dspmsg $ROHA_MSGS -s $ROHA_SET 414 \ "%1\$s: ERROR: unknown %2\$s LPAR. Provide valid name through -L option.\n" \ "$PROGNAME" "$g_partition" >&3 rc=$RC_PARAM_ERROR fi return $rc } # End of "process_halt()" #============================================================================= # # Name: get_hmc_param # # Description: Obtain HMC parameter by looking into HACMPhmc ODM object. Then, # if not found or default is set, look into HACMPhmcparam ODM # object. Otherwise set to default value. # # Arguments: $1 [INOUT] - output_value reference to the parameter # $2 [IN] - hmc HMC to get parameter from # $3 [IN] - attribute name of the HMC parameter to set # $4 [IN] - default_value default value to be set # # Environment: None # # Returns: RC_SUCCESS # #============================================================================= function get_hmc_param { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset -n output_value=$1 typeset hmc=$2 typeset attribute=$3 typeset -i default_value=$4 #======================================================= : First, look into HACMPhmc ODM. #======================================================= output_value=$(clodmget -q name=$hmc -f $attribute -n HACMPhmc 2>/dev/null) rc=$? if (( $rc > 0 || output_value == -1 || output_value == 0 )) ; then #========================================================================== : Then, look into HACMPhmcparam ODM, which stores the default for all HMCs. #========================================================================== output_value=$(clodmget -f default_$attribute -n HACMPhmcparam 2>/dev/null) rc=$? if (( $rc > 0 || output_value == 0 )) ; then #======================================================= : Then, set to default value received in parameter. #======================================================= output_value=$default_value rc=$RC_SUCCESS fi fi return $rc } # End of "get_hmc_param()" #============================================================================= # # Name: update_hmc_list # # Description: Update list of HMCs to fit the precedence order. # # Arguments: $@ [IN] first valid hmc # # Environment: g_hmc_list # # Returns: RC_SUCCESS # #============================================================================= function update_hmc_list { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset valid_hmc=$1 typeset param= #======================================================= # Build new HMC list. #======================================================= if echo $g_hmc_list | grep -q "[[:space:]]" ; then if [[ $valid_hmc == ${g_hmc_list%% *} ]] ; then g_hmc_list="$valid_hmc ${g_hmc_list#*$valid_hmc }" elif [[ $valid_hmc == ${g_hmc_list##* } ]] ; then g_hmc_list="$valid_hmc ${g_hmc_list% $valid_hmc*}" else g_hmc_list="$valid_hmc ${g_hmc_list#*$valid_hmc } ${g_hmc_list% $valid_hmc*}" fi fi #======================================================= # Persist new HMC list in HACMPdynresop ODM. #======================================================= param=$(ODMDIR="/etc/es/objrepos" clodmget -q "key=PREFERRED_HMC_LIST" HACMPdynresop 2>/dev/null) if [[ -n $param ]] ; then print -- "HACMPdynresop:\\nvalue=\"$g_hmc_list\"" | ODMDIR="/etc/es/objrepos" odmchange -o HACMPdynresop -q "key=PREFERRED_HMC_LIST" else print -- "HACMPdynresop:\\nkey=\"PREFERRED_HMC_LIST\"\\nvalue=\"$g_hmc_list\"" | ODMDIR="/etc/es/objrepos" odmadd fi return $RC_SUCCESS } # End of "update_hmc_list()" #============================================================================= # # Name: get_effective_version # # Description: Update the current effective HMC version for enterprise pool # operations to work with HMC levels 8.4/8.5 and above. # # Arguments: None # # Environment: g_hmc_list # # Returns: version # #============================================================================= function get_effective_version { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset ping_output="" typeset ping_cmd="ping -c 1 -w 3" typeset -i ping_rc=0 typeset param= typeset -i hmc_version=0 typeset version="" #========================================================= # Get the current effetive version from HACMPdynresop ODM. #========================================================= param=$(ODMDIR="/etc/es/objrepos" clodmget -q "key=EFFECTIVE_HMC_VERSION" -f value -n HACMPdynresop 2>/dev/null) if [[ -n $param ]] ; then return $param else for hmc in $g_hmc_list ; do #============================================ : Try to ping the HMC at address $hmc. #============================================ ping_output=$($ping_cmd $hmc >/dev/null 2>&1) ping_rc=$? if (( $ping_rc > 0 )) ; then #===================================================== : Cannot contact this HMC. Ask following HMC in list. #===================================================== dspmsg $ROHA_MSGS -s $ROHA_SET 500 \ "%1\$s: WARNING: unable to ping HMC at address %2\$s.\n" \ "$PROGNAME" "$hmc" >&3 continue fi hmccmdexec $hmc "lshmc -v" version rc=$? if (( $rc != 0 )) ; then continue else version=$(print "$version" | sed -n 's/.*\*RM \([^ ]\)/\1/p') version=$(print "$version" | cut -c 4,6) if (( $hmc_version == 0 || $hmc_version < $version )); then hmc_version=$version fi fi done fi #======================================================== # Persist the effective HMC version in HACMPdynresop ODM. #======================================================== if (( $hmc_version != 0 )) ; then param=$(ODMDIR="/etc/es/objrepos" clodmget -q "key=EFFECTIVE_HMC_VERSION" HACMPdynresop 2>/dev/null) if [[ -n $param ]] ; then print -- "HACMPdynresop:\\nvalue=\"$hmc_version\"" | ODMDIR="/etc/es/objrepos" odmchange -o HACMPdynresop -q "key=EFFECTIVE_HMC_VERSION" else print -- "HACMPdynresop:\\nkey=\"EFFECTIVE_HMC_VERSION\"\\nvalue=\"$hmc_version\"" | ODMDIR="/etc/es/objrepos" odmadd fi fi return $hmc_version } # End of "get_effective_version()" #============================================================================= # # Name: hmccmdexec # # Description: Execute the specified command on an HMC. The command run via a # password-less remote ssh connection, thus the HMC must have the # public key of the local node in its authorized keys list. Retry # delay and retry count are obtained from HACMPhmcparam ODM. # # The "-o StrictHostKeyChecking=no" tells ssh to automatically # add new host keys to the host key database file, without user # confirmation, for all first-time connection. # The "-o LogLevel=quiet" tells ssh to disable the display of the # warning message 'Warning: Permanently added 'host,ip' (RSA) to # the list of known hosts.'. # The "-o AddressFamily=any" tells ssh to work with both # IPv4 and IPv6. # The "-o BatchMode=yes" option forces ssh to not prompt for a # password. In order to run commands remotely via ssh the target # ssh machine must have the public key of this client machine. # If the target ssh machine does not have the public key of this # machine, then normally ssh prompts for a password, and # that causes this script to hang. But by using BatchMode, # if the target does not have our public key, then ssh # immediately returns an error. # The "-o ConnectTimeout=3" and "-o ConnectionAttempts=3" # tells ssh to wait for a maximum timeout of 9 seconds if # connection with the target machine cannot be established. # The "-o TCPKeepAlive=yes" tells ssh to send an empty TCP ACK # packet in order to keep the connection with remote target # opened. # # Arguments: $1 [IN] hmc - HMC to run the given commad # $2 [IN] cmd - command to run on the HMC. # $3 [OUT] ssh_ouput - reference to the output of the ssh command. # # Environment: g_hmc_list # g_enable_timeout # g_timeout # g_enterprise_pool # # Returns: RC_SUCCESS # RC_PING_ERROR # RC_SSH_ERROR # RC_REM_RES_BUSY_ERROR # RC_REM_CEC_BUSY_ERROR # RC_REM_NOT_ENOUGH_RES_ERROR # RC_REM_OTHER_ERROR # #============================================================================= function hmccmdexec { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset hmc=$1 cmd=$2 ccmd="" typeset -n ssh_output=$3 typeset ssh_cmd="eval LC_ALL=C ssh -o StrictHostKeyChecking=no -o LogLevel=quiet -o AddressFamily=any -o BatchMode=yes -o ConnectTimeout=3 -o ConnectionAttempts=3 -o TCPKeepAlive=no" typeset -i ssh_rc=0 typeset res="" typeset hmcuser="" # Get HMC User from HACMPhmc hmcuser=$(clodmget -n -q name=$hmc -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]]; then # Use FQDN and try again from HACMPhmc typeset fqdn_hmc=$(host $hmc | awk '{print $1}') [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -n -q name=${fqdn_hmc} -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]];then # If we are here means, either we are running clhmccmd very first time or no hmc user is configured to PowerHA. typeset cust_hmcuser=$hmc"_user" hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then cust_hmcuser=$fqdn_hmc"_user" [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then # None of methods works to get HMC user name, hence use hscroot hmcuser="hscroot" fi fi fi fi # : g_enable_timeout=$g_enable_timeout # if (( g_enable_timeout == 1 )) ; then # : g_enable_timeout is set on acquire/release dlpar operation. : g_timeout has been computed accordingly to the amount of : resources to be acquired/released : g_timeout=$g_timeout. # get_hmc_param hmc_timeout "$hmc" timeout 5 # : We add to the g_timeout, the default timeout set on this hmc : $hmc_timeout # (( hmc_timeout = $g_timeout + $hmc_timeout )) # : hmc_timeout=$hmc_timeout : Timeout value is expressed in minutes. # ccmd="$cmd -w $hmc_timeout" else ccmd="$cmd" fi #======================================================= : Get retry count and retry delay. #======================================================= typeset -i hmc_retry_cnt=0 hmc_retry_dly=0 get_hmc_param hmc_retry_cnt "$hmc" retry_count 5 get_hmc_param hmc_retry_dly "$hmc" retry_delay 10 for (( i=1 ; i <= hmc_retry_cnt ; i++ )) ; do #======================================================= : Try to ssh the command on HMC at address $hmc. #======================================================= : Start ssh command at $(LC_ALL=C date) ssh_output=$($ssh_cmd "$hmcuser@$hmc '$ccmd 2>&1'") ssh_rc=$? : Return from ssh command at $(LC_ALL=C date) if (( $ssh_rc == 255 )) ; then #======================================================= : Cannot ssh the command. Do not retry. Break out from : the retry loop. #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 501 \ "%1\$s: WARNING: unable to ssh HMC at address %2\$s.\n" \ "$PROGNAME" "$hmc" >&3 rc=$RC_SSH_ERROR g_enable_update_hmc=1 break elif (( $ssh_rc > 0 )) ; then ssh_output=$(print -n $ssh_output | sed -e "s/\-q/\-m/g") typeset code=${ssh_output%% *} case $code in "HSCL2932"|"HSCL294F") # "Operation completed partially" condition #======================================================= : The remote command fails acquiring/releasing busy : resources or timed out. The operation may have : completed partially. Break out from the retry loop. #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 430 \ "%1\$s: ERROR: HMC %2\$s returns %3\$s error code when running command \"%4\$s\":\n%5\$s\n" \ "$PROGNAME" "$hmc" "$code" "$ccmd" "$ssh_output" >&3 rc=$RC_REM_RES_BUSY_ERROR break ;; "HSCL3205") # "Managed System busy" condition #======================================================= : The remote command fails because managed system is : busy. Retry asking this same HMC or the following HMC : in the list. #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 504 \ "%1\$s: WARNING: HMC %2\$s returns %3\$s error code when running command \"%4\$s\" (attempt %5\$d/%6\$d):\n%7\$s\n" \ "$PROGNAME" "$hmc" "$code" "$ccmd" "$i" "$hmc_retry_cnt" "$ssh_output" >&3 rc=$RC_REM_CEC_BUSY_ERROR ;; "HSCL03F9"|"HSCL2914"|"HSCL1453"|"HSCL90A4"|"HSCL909F"|"HSCL9028"\ |"HSCL9029"|"HSCL90E7"|"HSCL90E8"|"HSCL9026"|"HSCL9027"|"HSCL9052"|"HSCL9053") # "Not enough resources" condition # http://www.ibm.com/support/knowledgecenter/POWER5/ipha5_p5/hscl_9xxx.htm #======================================================= : The remote command fails beacuse there are not enough : available resources. Break out from the retry loop. #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 430 \ "%1\$s: ERROR: HMC %2\$s returns %3\$s error code when running command \"%4\$s\":\n%5\$s\n" \ "$PROGNAME" "$hmc" "$code" "$ccmd" "$ssh_output" >&3 rc=$RC_REM_NOT_ENOUGH_RES_ERROR break ;; "HSCL90A8"|"HSCL900B"|"HSCL900C") # HSCL90A8 The number of Mobile CoD processors to remove cannot exceed 4, # which is the number of Mobile CoD processors that are currently assigned to the managed system. # HSCL900B This operation is not allowed because On/Off Capacity on Demand for processors is not # supported on the managed system. # HSCL900C This operation is not allowed because On/Off Capacity on Demand for memory is not # supported on the managed system. #======================================================= : Break out from the retry loop. #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 430 \ "%1\$s: ERROR: HMC %2\$s returns %3\$s error code when running command \"%4\$s\":\n%5\$s\n" \ "$PROGNAME" "$hmc" "$code" "$ccmd" "$ssh_output" >&3 rc=$RC_REM_OTHER_ERROR break ;; "HSCL8018") # HSCL8018 The managed system was not found. #======================================================= : Break out from the retry loop. #======================================================= rc=$RC_CEC_NOT_FOUND break ;; *) if [[ $code != HSCL* ]] ; then code="unknown" fi #======================================================= : Error executing the remote command. Break out from the : retry loop. #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 430 \ "%1\$s: ERROR: HMC %2\$s returns %3\$s error code when running command \"%4\$s\":\n%5\$s\n" \ "$PROGNAME" "$hmc" "$code" "$ccmd" "$ssh_output" >&3 rc=$RC_REM_OTHER_ERROR break ;; esac else #======================================================= : Success. Break out from the retry loop and HMC loop, : except if we still have to search for a new backup HMC #======================================================= rc=$RC_SUCCESS break fi sleep $hmc_retry_dly done return $rc } # End of "hmccmdexec()" #============================================================================= # # Name: clhmcexec # # Description: Execute the specified command on an HMC. Each HMC defined on # the local node will be contacted until one responds. The # command is run via a password-less remote ssh connection, thus # the HMC must have the public key of the local node in its # authorized keys list. Retry delay and retry count are obtained # from ODM object HACMPhmcparam. # # The "-o StrictHostKeyChecking=no" tells ssh to automatically # add new host keys to the host key database file, without user # confirmation, for all first-time connection. # The "-o LogLevel=quiet" tells ssh to disable the display of the # warning message 'Warning: Permanently added 'host,ip' (RSA) to # the list of known hosts.'. # The "-o AddressFamily=any" tells ssh to work with both # IPv4 and IPv6. # The "-o BatchMode=yes" option forces ssh to not prompt for a # password. In order to run commands remotely via ssh the target # ssh machine must have the public key of this client machine. # If the target ssh machine does not have the public key of this # machine, then normally ssh prompts for a password, and # that causes this script to hang. But by using BatchMode, # if the target does not have our public key, then ssh # immediately returns an error. # The "-o ConnectTimeout=3" and "-o ConnectionAttempts=3" # tells ssh to wait for a maximum timeout of 9 seconds if # connection with the target machine cannot be established. # The "-o TCPKeepAlive=yes" tells ssh to send an empty TCP ACK # packet in order to keep the connection with remote target # opened. # # Arguments: $1 [IN] cmd - command line to run on the HMC. # $2 [OUT] ssh_ouput - reference to the output of the ssh command. # # Environment: g_hmc_list # g_epcod_modify_operation # g_enable_timeout # g_timeout # g_enterprise_pool # # Returns: RC_SUCCESS # RC_PING_ERROR # RC_SSH_ERROR # RC_REM_RES_BUSY_ERROR # RC_REM_CEC_BUSY_ERROR # RC_REM_NOT_ENOUGH_RES_ERROR # RC_REM_OTHER_ERROR # #============================================================================= function clhmcexec { [[ ${VERBOSE_LOGGING:-} == high ]] && set -x typeset -i rc=$RC_SUCCESS typeset cmd=$1 ccmd="" typeset ping_output="" typeset ping_cmd="ping -c 1 -w 3" typeset -i ping_rc=0 typeset -n ssh_output=$2 typeset ssh_output_bkupchange="" typeset ssh_cmd="eval LC_ALL=C ssh -o StrictHostKeyChecking=no -o LogLevel=quiet -o AddressFamily=any -o BatchMode=yes -o ConnectTimeout=3 -o ConnectionAttempts=3 -o TCPKeepAlive=no" typeset -i ssh_rc=0 typeset -i loop_hmc_counter=0; typeset -i looking_for_new_backup=0; typeset res="" typeset hmcuser="" typeset -i version=0 typeset -i release=0 typeset -i service_pack=0 typeset set_type="setmaster" version=$(echo $hmc_version | awk -F[\V\R] '{print $2}') release=$(echo $hmc_version | awk -F[\R\.] '{print $2}') service_pack=$(echo $hmc_version | awk -F[\.\.] '{print $2}') # For HMC version 10 or higher, setcontroller should be used to set one of the HMC as primary HMC. if [[ -n $version && -n $release && -n $service_pack ]] && (( $version > 10 )) || (( $version >= 10 && (( $release > 0 ) || ( $release >= 0 && $service_pack >= 1010 )) )) ; then set_type="setcontroller" fi if (( g_epcod_modify_operation == 0 )) ; then for hmc in $g_hmc_list ; do #============================================ : Try to ping the HMC at address $hmc. #============================================ ping_output=$($ping_cmd $hmc >/dev/null 2>&1) ping_rc=$? if (( $ping_rc > 0 )) ; then #===================================================== : Cannot contact this HMC. Ask following HMC in list. #===================================================== dspmsg $ROHA_MSGS -s $ROHA_SET 500 \ "%1\$s: WARNING: unable to ping HMC at address %2\$s.\n" \ "$PROGNAME" "$hmc" >&3 rc=$RC_PING_ERROR g_enable_update_hmc=1 continue fi hmccmdexec $hmc "$cmd" ssh_output rc=$? if (( rc == RC_SSH_ERROR || rc == RC_CEC_NOT_FOUND )); then continue else break fi done if (( rc == $RC_SUCCESS && g_enable_update_hmc == 1 )) ; then update_hmc_list "$hmc" g_enable_update_hmc=0 elif (( rc == RC_CEC_NOT_FOUND )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 521 \ "%1\$s: ERROR: Failed to get the Managed System when running command \"%2\$s\":\n%3\$s\n" \ "$PROGNAME" "$cmd" "$ssh_output" >&3 fi else #=================================================== : Get the Effective HMC level for EPCOD operations #================================================== get_effective_version typeset -i version=$? if (( $version < $CROSS_HMC_VERSION )); then #======================================================= : If working on an EPCoD Operation, we need master and : backup_master hmcs, read only once #======================================================= if [[ -z $g_master_hmc ]] ; then for hmc in $g_hmc_list ; do ping_output=$($ping_cmd $hmc >/dev/null 2>&1) ping_rc=$? if (( $ping_rc > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 500 \ "%1\$s: WARNING: unable to ping HMC at address %2\$s.\n" \ "$PROGNAME" "$hmc" >&3 rc=$RC_PING_ERROR g_enable_update_hmc=1 else # Get HMC User from HACMPhmc hmcuser=$(clodmget -n -q name=$hmc -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]]; then # Use FQDN and try again from HACMPhmc typeset fqdn_hmc=$(host $hmc | awk '{print $1}') [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -n -q name=${fqdn_hmc} -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]];then # If we are here means, either we are running clhmccmd very first time or no hmc user is configured to PowerHA. typeset cust_hmcuser=$hmc"_user" hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then cust_hmcuser=$fqdn_hmc"_user" [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then # None of methods works to get HMC user name, hence use hscroot hmcuser="hscroot" fi fi fi fi res=$($ssh_cmd "$hmcuser@$hmc 'lscodpool -p $g_enterprise_pool --level pool -F master_mc_name:backup_master_mc_name 2>&1'") ssh_rc=$? if (( ssh_rc > 0 )) ; then #======================================================= : If an error occured, ask the following HMC in the list. #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 502 \ "%1\$s: WARNING: unable to query Master HMC at address %2\$s from HMC at address %3\$s for %4\$s Enterprise Pool CoD.\n" \ "$PROGNAME" "$master_hmc" "$hmc" "$g_enterprise_pool" >&3 rc=$RC_PARAM_ERROR #======================================================= : Do not update HMC list if it is because HMC does not : know the pool #======================================================= [[ ${res%% *} != "HSCL8029" ]] && g_enable_update_hmc=1 continue else print "$res" | IFS=: read g_master_hmc g_backup_hmc rc=$RC_SUCCESS; break; fi fi done if (( rc == $RC_SUCCESS && g_enable_update_hmc == 1 )) ; then update_hmc_list "$hmc" g_enable_update_hmc=0 fi if (( rc != $RC_SUCCESS )) || [[ -z $g_master_hmc ]] ; then return $rc fi fi #======================================================= : Priority to use master or backup hmc in case of epcod : modify operation #======================================================= if (( g_epcod_modify_operation == 1 )) ; then loop_hmc_list="$g_master_hmc $g_backup_hmc $g_hmc_list" fi #======================================================= : Loop through HMC list in case of ping or ssh failure. #======================================================= for hmc in $loop_hmc_list ; do #======================================================= : In case of epcod modify operation, loop_hmc_counter : value will be 1 for master hmc, 2 for backup_master : hmc and greater than 2 for other hmcs, also : re-including master and backup. We may just compare : string but it would cost more expensive #======================================================= (( loop_hmc_counter++ )) #======================================================= : For epcod modify op, if there was no backup_hmc, skip : loop_hmc_counter value 2 #======================================================= (( loop_hmc_counter == 2 )) && [[ -z $g_backup_hmc ]] \ && (( loop_hmc_counter++ )) if (( loop_hmc_counter > 2 )) ; then #======================================================= : Either g_backup_hmc contains the hmc which was master at begin : g_master_hmc contains the hmc which was backup at begin : those have both already been tested. : Or g_backup_hmc was empty #======================================================= if (( looking_for_new_backup == 1 )) ; then #======================================================= # Executed only if # Master was unreachable # Backup setted as new master # Command already executed on the new master # If an HMC is found for being set as new backup, its # connectivity has to be checked before doing the change #======================================================= [[ $(LC_ALL=C host $hmc | awk '{print $3}') == $(LC_ALL=C host $g_backup_hmc | awk '{print $3}') ]] \ || [[ $(LC_ALL=C host $hmc | awk '{print $3}') == $(LC_ALL=C host $g_master_hmc | awk '{print $3}') ]] \ && continue else #======================================================= : Neither master_hmc nor backup_master_hmc is reachable : EPCoD modify operation cannot be done #======================================================= break fi fi #============================================ : Try to ping the HMC at address $hmc. #============================================ ping_output=$($ping_cmd $hmc >/dev/null 2>&1) ping_rc=$? if (( $ping_rc > 0 )) ; then #===================================================== : Cannot contact this HMC. Ask following HMC in list. #===================================================== dspmsg $ROHA_MSGS -s $ROHA_SET 500 \ "%1\$s: WARNING: unable to ping HMC at address %2\$s.\n" \ "$PROGNAME" "$hmc" >&3 if (( looking_for_new_backup == 0 )) ; then rc=$RC_PING_ERROR g_enable_update_hmc=1 fi continue fi #======================================================= : If executing an epcod modify operation, make sure that : the hmc is the master_hmc #======================================================= if (( loop_hmc_counter != 1 )) ; then #======================================================= : If not, we need to change master_hmc, we also try to : set a backup_master_hmc : Change only on HMC failure, so do not use --force #======================================================= if (( loop_hmc_counter == 2 )) ; then # Get HMC User from HACMPhmc hmcuser=$(clodmget -n -q name=$hmc -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]]; then # Use FQDN and try again from HACMPhmc typeset fqdn_hmc=$(host $hmc | awk '{print $1}') [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -n -q name=${fqdn_hmc} -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]];then # If we are here means, either we are running clhmccmd very first time or no hmc user is configured to PowerHA. typeset cust_hmcuser=$hmc"_user" hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then cust_hmcuser=$fqdn_hmc"_user" [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then # None of methods works to get HMC user name, hence use hscroot hmcuser="hscroot" fi fi fi fi ssh_output=$($ssh_cmd "$hmcuser@$hmc 'chcodpool -p $g_enterprise_pool -o $set_type --mc this 2>&1'") ssh_rc=$? if (( ssh_rc > 0 )) ; then #======================================================= : If an error occured, then both master and backup_master : hmc were unable to be accessed. Cannot execute command #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 503 \ "%1\$s: WARNING: unable to change Master HMC from %2\$s to %3\$s for %4\$s Enterprise Pool CoD.\n%5\$s\n" \ "$PROGNAME" "$g_master_hmc" "$g_backup_hmc" "$g_enterprise_pool" "$ssh_output" >&3 rc=$RC_PARAM_ERROR return $rc else # ! (ssh_rc > 0) dspmsg $ROHA_MSGS -s $ROHA_SET 505 \ "%1\$s: WARNING: Master HMC has been changed from %2\$s to %3\$s for %4\$s Enterprise Pool CoD.\n" \ "$PROGNAME" "$g_master_hmc" "$g_backup_hmc" "$g_enterprise_pool" >&3 sleep 15 # give time for new master to be updated #======================================================= : Next steps are to execute operation and then to find : and set a new backup master hmc. If no valid hmc can : be found then the old master hmc is tried #======================================================= g_backup_hmc=$g_master_hmc g_master_hmc=$hmc looking_for_new_backup=1 fi # (ssh_rc > 0) else # ! (loop_hmc_counter == 2) #======================================================= : When g_epcod_modify_operation value is 1, we only go : beyond loop_hmc_counter value 2 if we are looking for : a new backup master hmc #======================================================= # Get Master HMC User from HACMPhmc typeset master_hmc_user=$(clodmget -n -q name=$g_master_hmc -f user HACMPhmc 2>/dev/null) if [[ -z "$master_hmc_user" ]]; then # Use FQDN and try again from HACMPhmc typeset fqdn_hmc=$(host $g_master_hmc | awk '{print $1}') [[ ${fqdn_hmc} != $g_master_hmc ]] && master_hmc_user=$(clodmget -n -q name=${fqdn_hmc} -f user HACMPhmc 2>/dev/null) if [[ -z "$master_hmc_user" ]];then # If we are here means, either we are running clhmccmd very first time or no hmc user is configured to PowerHA. typeset masteruser=$g_master_hmc"_user" master_hmc_user=$(clodmget -q " type=verify_dlpar AND description=$masteruser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$master_hmc_user" ]];then masteruser=$fqdn_hmc"_user" [[ ${fqdn_hmc} != $g_master_hmc ]] && master_hmc_user=$(clodmget -q " type=verify_dlpar AND description=$masteruser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$master_hmc_user" ]];then # None of methods works to get Master HMC user name, hence use hscroot master_hmc_user="hscroot" fi fi fi fi ssh_output_bkupchange=$($ssh_cmd "$master_hmc_user@$g_master_hmc 'chcodpool -p $g_enterprise_pool -o update -a \"backup_master_mc_name=${hmc%%.*}\" 2>&1'") ssh_rc=$? if (( ssh_rc > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 0 \ "%1\$s: WARNING: unable to set new Backup HMC %2\$s for %3\$s Enterprise Pool CoD.\n%4\$s\n" \ "$PROGNAME" "$hmc" "$g_enterprise_pool" "$ssh_output_bkupchange" >&3 continue else g_backup_hmc=$hmc looking_for_new_backup=0 break fi fi # (loop_hmc_counter == 2) fi # ( loop_hmc_counter != 1 ) #======================================================= : When the correct hmc is found, execute operation #======================================================= hmccmdexec $hmc "$cmd" ssh_output rc=$? if (( rc == RC_SSH_ERROR )) ; then continue elif (( looking_for_new_backup == 1 )) ; then #======================================================= : Success. Break out from the HMC loop, except if we : still have to search for a new backup HMC #======================================================= continue else break fi done if (( looking_for_new_backup == 1 )) ; then #======================================================= : We were unable to find a new backup HMC, so we : will try to set the old master as the new backup #======================================================= # Get Master HMC User from HACMPhmc typeset master_hmc_user=$(clodmget -n -q name=$g_master_hmc -f user HACMPhmc 2>/dev/null) if [[ -z "$master_hmc_user" ]]; then # Use FQDN and try again from HACMPhmc typeset fqdn_hmc=$(host $g_master_hmc | awk '{print $1}') [[ ${fqdn_hmc} != $g_master_hmc ]] && master_hmc_user=$(clodmget -n -q name=${fqdn_hmc} -f user HACMPhmc 2>/dev/null) if [[ -z "$master_hmc_user" ]];then # If we are here means, either we are running clhmccmd very first time or no hmc user is configured to PowerHA. typeset masteruser=$g_master_hmc"_user" master_hmc_user=$(clodmget -q " type=verify_dlpar AND description=$masteruser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$master_hmc_user" ]];then masteruser=$fqdn_hmc"_user" [[ ${fqdn_hmc} != $g_master_hmc ]] && master_hmc_user=$(clodmget -q " type=verify_dlpar AND description=$masteruser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$master_hmc_user" ]];then # None of methods works to get Master HMC user name, hence use hscroot master_hmc_user="hscroot" fi fi fi fi ssh_output_bkupchange=$($ssh_cmd "$master_hmc_user@$g_master_hmc 'chcodpool -p $g_enterprise_pool -o update -a \"backup_master_mc_name=${hmc%%.*}\" 2>&1'") ssh_rc=$? if (( ssh_rc > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 0 \ "%1\$s: WARNING: unable to set new Backup HMC %2\$s for %3\$s Enterprise Pool CoD.\n%4\$s\n" \ "$PROGNAME" "$hmc" "$g_enterprise_pool" "$ssh_output_bkupchange" >&3 g_backup_hmc="" fi looking_for_new_backup=0 fi else #====================================================== : If working on an EPCoD Operation, we need master hmc #====================================================== if [[ -z $g_master_hmc ]] ; then for hmc in $g_hmc_list ; do ping_output=$($ping_cmd $hmc >/dev/null 2>&1) ping_rc=$? if (( $ping_rc > 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 500 \ "%1\$s: WARNING: unable to ping HMC at address %2\$s.\n" \ "$PROGNAME" "$hmc" >&3 rc=$RC_PING_ERROR g_enable_update_hmc=1 else # Get HMC User from HACMPhmc hmcuser=$(clodmget -n -q name=$hmc -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]]; then # Use FQDN and try again from HACMPhmc typeset fqdn_hmc=$(host $hmc | awk '{print $1}') [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -n -q name=${fqdn_hmc} -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]];then # If we are here means, either we are running clhmccmd very first time or no hmc user is configured to PowerHA. typeset cust_hmcuser=$hmc"_user" hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then cust_hmcuser=$fqdn_hmc"_user" [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then # None of methods works to get HMC user name, hence use hscroot hmcuser="hscroot" fi fi fi fi res=$($ssh_cmd "$hmcuser@$hmc 'lscodpool -p $g_enterprise_pool --level pool -F master_mc_name 2>&1'") ssh_rc=$? if (( ssh_rc > 0 )) ; then #======================================================= : If an error occured, ask the following HMC in the list. #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 502 \ "%1\$s: WARNING: unable to query Master HMC at address %2\$s from HMC at address %3\$s for %4\$s Enterprise Pool CoD.\n" \ "$PROGNAME" "$master_hmc" "$hmc" "$g_enterprise_pool" >&3 rc=$RC_PARAM_ERROR #======================================================= : Do not update HMC list if it is because HMC does not : know the pool #======================================================= [[ ${res%% *} != "HSCL8029" ]] && g_enable_update_hmc=1 continue else print "$res" | IFS=: read g_master_hmc rc=$RC_SUCCESS; break; fi fi done if (( rc == $RC_SUCCESS && g_enable_update_hmc == 1 )) ; then update_hmc_list "$hmc" g_enable_update_hmc=0 fi if (( rc != $RC_SUCCESS )) || [[ -z $g_master_hmc ]] ; then return $rc fi fi #======================================================= : Priority to use master or backup hmc in case of epcod : modify operation #======================================================= if (( g_epcod_modify_operation == 1 )) ; then loop_hmc_list="$g_master_hmc $g_hmc_list" fi #======================================================= : Loop through HMC list in case of ping or ssh failure. #======================================================= for hmc in $loop_hmc_list ; do #======================================================= : In case of epcod modify operation, loop_hmc_counter : value will be 1 for master hmc #======================================================= (( loop_hmc_counter++ )) #======================================================= : Try to ping the HMC at address $hmc. #======================================================= ping_output=$($ping_cmd $hmc >/dev/null 2>&1) ping_rc=$? if (( $ping_rc > 0 )) ; then #======================================================= : Cannot contact this HMC. Ask following HMC in list. #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 500 \ "%1\$s: WARNING: unable to ping HMC at address %2\$s.\n" \ "$PROGNAME" "$hmc" >&3 continue fi #======================================================= : If executing an epcod modify operation, make sure that : the hmc is the master_hmc : HMC should be part of EPCoD before changing as master #======================================================= if (( loop_hmc_counter != 1 )) ; then #======================================================= : If not, we need to change master_hmc : Change only on HMC failure, so do not use --force #======================================================= # Get HMC User from HACMPhmc hmcuser=$(clodmget -n -q name=$hmc -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]]; then # Use FQDN and try again from HACMPhmc typeset fqdn_hmc=$(host $hmc | awk '{print $1}') [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -n -q name=${fqdn_hmc} -f user HACMPhmc 2>/dev/null) if [[ -z "$hmcuser" ]];then # If we are here means, either we are running clhmccmd very first time or no hmc user is configured to PowerHA. typeset cust_hmcuser=$hmc"_user" hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then cust_hmcuser=$fqdn_hmc"_user" [[ ${fqdn_hmc} != $hmc ]] && hmcuser=$(clodmget -q " type=verify_dlpar AND description=$cust_hmcuser " -nf value HACMPcustom 2>/dev/null) if [[ -z "$hmcuser" ]];then # None of methods works to get HMC user name, hence use hscroot hmcuser="hscroot" fi fi fi fi ssh_output=$($ssh_cmd "$hmcuser@$hmc 'chcodpool -p $g_enterprise_pool -o $set_type --mc this 2>&1'") ssh_rc=$? if (( ssh_rc > 0 )) ; then print $ssh_output | grep -q -i "specify the --force option" if (( $? == 0 )) ; then dspmsg $ROHA_MSGS -s $ROHA_SET 536 \ "%1\$s: WARNING: unable to change Master HMC from %2\$s to %3\$s for %4\$s Enterprise Pool CoD.\n%5\$s.. Now trying with force option.\n" \ "$PROGNAME" "$g_master_hmc" "$hmc" "$g_enterprise_pool" "$ssh_output" >&3 #======================================================= : Change master returns failure, try with --force option #======================================================= ssh_output=$($ssh_cmd "$hmcuser@$hmc 'chcodpool -p $g_enterprise_pool -o $set_type --force --mc this 2>&1'") ssh_rc=$? if (( ssh_rc > 0 )) ; then res=$($ssh_cmd "$hmcuser@$hmc 'lscodpool -p $g_enterprise_pool --level pool -F master_mc_name 2>&1'") if (( $? == 0 )) && [[ -n $res && $res != $g_master_hmc ]]; then ssh_rc=0 fi fi fi fi if (( ssh_rc > 0 )) ; then #======================================================= : If an error occured, then master hmc were unable to be : accessed. Cannot execute command #======================================================= dspmsg $ROHA_MSGS -s $ROHA_SET 503 \ "%1\$s: WARNING: unable to change Master HMC from %2\$s to %3\$s for %4\$s Enterprise Pool CoD.\n%5\$s\n" \ "$PROGNAME" "$g_master_hmc" "$hmc" "$g_enterprise_pool" "$ssh_output" >&3 rc=$RC_PARAM_ERROR return $rc else # ! (ssh_rc > 0) dspmsg $ROHA_MSGS -s $ROHA_SET 505 \ "%1\$s: WARNING: Master HMC has been changed from %2\$s to %3\$s for %4\$s Enterprise Pool CoD.\n" \ "$PROGNAME" "$g_master_hmc" "$hmc" "$g_enterprise_pool" >&3 sleep 15 # give time for new master to be updated g_master_hmc=$hmc fi # (ssh_rc > 0) fi # ( loop_hmc_counter != 1 ) #======================================================= : When the correct hmc is found, execute operation #======================================================= hmccmdexec $hmc "$cmd" ssh_output rc=$? if (( rc == RC_SSH_ERROR )) ; then continue else break fi done fi fi return $rc } # End of "clhmcexec()" ############################################################################### ############################################################################### ## ## MAIN ## ############################################################################### ############################################################################### #============================================================================= # Attributes #============================================================================= typeset -r HMC_ATTRS="\ hmc_list \ hmc_version" typeset -r MANAGED_SYSTEM_ATTRS="\ local_sys_name \ sys_name \ sys_lpar_names \ sys_state \ sys_type_model \ cod_mem_capable \ cod_proc_capable \ mem_region_size \ installed_sys_mem \ configurable_sys_mem \ deconfig_sys_mem \ sys_firmware_mem \ curr_avail_sys_mem \ curr_free_sys_mem \ installed_sys_proc_units \ configurable_sys_proc_units \ curr_avail_sys_proc_units \ curr_free_sys_proc_units \ deconfig_sys_proc_units \ min_proc_units_per_virtual_proc" typeset -r PARTITION_ATTRS="\ local_lpar_name \ lpar_name \ lpar_id \ uuid \ lpar_state \ curr_profile \ lpar_avail_priority \ curr_proc_mode \ curr_min_mem \ curr_mem \ curr_max_mem \ curr_min_procs \ curr_procs \ curr_max_procs \ curr_min_proc_units \ curr_proc_units \ curr_max_proc_units \ curr_shared_proc_pool_name" typeset -r PROFILE_ATTRS="\ local_prof_name \ prof_name \ prof_proc_mode \ prof_sharing_mode \ prof_shared_procpool \ prof_minimum_mem \ prof_minimum_procs \ prof_minimum_proc_units \ prof_desired_mem \ prof_desired_procs \ prof_desired_proc_units \ prof_maximum_mem \ prof_maximum_procs \ prof_maximum_proc_units" typeset -r SHARED_PROC_POOL_ATTRS="\ local_procpool_name \ procpool_name \ max_pool_proc_units \ curr_free_pool_proc_units \ curr_reserved_pool_proc_units" typeset -r TRIAL_COD_ATTRS="\ mem_trial_state \ activated_trial_mem \ mem_trial_days_left \ mem_trial_hours_left \ proc_trial_state \ activated_trial_procs \ proc_trial_days_left \ proc_trial_hours_left" typeset -r ONOFF_COD_ATTRS="\ proc_onoff_state \ activated_onoff_procs \ avail_procs_for_onoff \ unreturned_onoff_procs \ onoff_request_proc_days_left \ onoff_proc_day_hours_left \ onoff_proc_days_avail \ mem_onoff_state \ activated_onoff_mem \ avail_mem_for_onoff \ unreturned_onoff_mem \ onoff_request_mem_days_left \ onoff_mem_day_hours_left \ onoff_mem_days_avail" typeset -r ENTERPRISE_POOL_ATTRS="\ local_codpool_name \ codpool_name \ codpool_sys_names \ mobile_state \ master_mc_name \ backup_master_mc_name \ mobile_mem \ avail_mobile_mem \ unreturned_mobile_mem \ sys_mobile_mem \ sys_unreturned_mobile_mem \ sys_inactive_mem \ mobile_procs \ avail_mobile_procs \ unreturned_mobile_procs \ sys_mobile_procs \ sys_unreturned_mobile_procs \ sys_inactive_procs" typeset -r GENERAL_ATTRS="\ hmc_list \ hmc_version \ local_sys_name \ sys_name \ sys_lpar_names \ sys_state \ sys_type_model \ local_lpar_name \ lpar_name \ lpar_id \ uuid \ lpar_state \ curr_profile \ local_prof_name \ prof_name \ local_procpool_name \ procpool_name \ local_codpool_name \ codpool_name \ codpool_sys_names \ mobile_state \ master_mc_name \ backup_master_mc_name" typeset -r PROCESSOR_ATTRS="\ cod_proc_capable \ installed_sys_proc_units \ configurable_sys_proc_units \ deconfig_sys_proc_units \ curr_avail_sys_proc_units \ curr_free_sys_proc_units \ min_proc_units_per_virtual_proc \ prof_minimum_procs \ prof_minimum_proc_units \ prof_desired_procs \ prof_desired_proc_units \ prof_maximum_procs \ prof_maximum_proc_units \ prof_proc_mode \ prof_sharing_mode \ prof_shared_procpool \ curr_proc_mode \ curr_min_procs \ curr_procs \ curr_max_procs \ curr_min_proc_units \ curr_proc_units \ curr_max_proc_units \ curr_shared_proc_pool_name \ max_pool_proc_units \ curr_free_pool_proc_units \ curr_reserved_pool_proc_units \ proc_trial_state \ activated_trial_procs \ proc_trial_days_left \ proc_trial_hours_left \ proc_onoff_state \ activated_onoff_procs \ avail_procs_for_onoff \ unreturned_onoff_procs \ onoff_request_proc_days_left \ onoff_proc_day_hours_left \ onoff_proc_days_avail \ mobile_procs \ avail_mobile_procs \ unreturned_mobile_procs \ sys_mobile_procs \ sys_unreturned_mobile_procs \ sys_inactive_procs" typeset -r MEMORY_ATTRS="\ cod_mem_capable \ mem_region_size \ installed_sys_mem \ configurable_sys_mem \ deconfig_sys_mem \ sys_firmware_mem \ curr_avail_sys_mem \ curr_free_sys_mem \ prof_minimum_mem \ prof_desired_mem \ prof_maximum_mem \ curr_min_mem \ curr_mem \ curr_max_mem \ mem_trial_state \ activated_trial_mem \ mem_trial_days_left \ mem_trial_hours_left \ mem_onoff_state \ activated_onoff_mem \ avail_mem_for_onoff \ unreturned_onoff_mem \ onoff_request_mem_days_left \ onoff_mem_day_hours_left \ onoff_mem_days_avail \ mobile_mem \ avail_mobile_mem \ unreturned_mobile_mem \ sys_mobile_mem \ sys_unreturned_mobile_mem \ sys_inactive_mem" typeset -r AVAIL_ATTRS="\ curr_free_sys_mem \ onoff_mem_days_avail \ avail_mobile_mem \ curr_free_sys_proc_units \ onoff_proc_days_avail \ avail_mobile_procs" typeset -r CURRENT_ATTRS="\ curr_mem \ curr_procs \ curr_proc_units \ activated_onoff_mem \ onoff_request_mem_days_left \ activated_onoff_procs \ onoff_request_proc_days_left \ sys_mobile_mem \ sys_mobile_procs" typeset -r QUERY_ATTR_LIST="\ $HMC_ATTRS \ $MANAGED_SYSTEM_ATTRS \ $PARTITION_ATTRS \ $PROFILE_ATTRS \ $SHARED_PROC_POOL_ATTRS \ $TRIAL_COD_ATTRS \ $ONOFF_COD_ATTRS \ $ENTERPRISE_POOL_ATTRS" typeset -r CHANGE_ATTR_LIST="\ max_pool_proc_units \ reserved_pool_proc_units" typeset -r OPERATION_LIST="\ query \ change \ acquire \ release \ halt" typeset -r RESOURCE_LIST="\ dlpar \ onoff \ epcod" #============================================================================= # Conversion tables # intended to convert attributes to be comprehensible by a specific version # of HMC. # Key used in g_convtabHMC78 is the attribute passed to clhmccmd, while value # is the attribute passed to hmc command. #============================================================================= typeset -A g_convtabHMC78 #======================================================= # 0. local #======================================================= g_convtabHMC78[hmc_list]="" # Not supported by HMC - internally computed g_convtabHMC78[hmc_version]="" # Not supported by HMC - internally computed g_convtabHMC78[local_sys_name]="" # Not supported by HMC - internally computed g_convtabHMC78[local_lpar_name]="" # Not supported by HMC - internally computed g_convtabHMC78[local_prof_name]="" # Not supported by HMC - internally computed g_convtabHMC78[local_procpool_name]="" # Not supported by HMC - internally computed g_convtabHMC78[local_codpool_name]="" # Not supported by HMC - internally computed #======================================================= # 1. cec_sys (lssyscfg -m $g_managed_system -r sys) #======================================================= g_convtabHMC78[sys_name]="name" g_convtabHMC78[sys_state]="state" g_convtabHMC78[sys_lpar_names]="" # Not supported by HMC - internally computed g_convtabHMC78[sys_type_model]="type_model" g_convtabHMC78[cod_mem_capable]="cod_mem_capable" g_convtabHMC78[cod_proc_capable]="cod_proc_capable" #======================================================= # 2. cec_mem (lshwres -m $g_managed_system --level sys -r mem) #======================================================= g_convtabHMC78[mem_region_size]="mem_region_size" g_convtabHMC78[installed_sys_mem]="installed_sys_mem" g_convtabHMC78[configurable_sys_mem]="configurable_sys_mem" g_convtabHMC78[deconfig_sys_mem]="deconfig_sys_mem" g_convtabHMC78[sys_firmware_mem]="sys_firmware_mem" g_convtabHMC78[curr_avail_sys_mem]="curr_avail_sys_mem" g_convtabHMC78[curr_free_sys_mem]="" # Not supported by HMC - internally computed #======================================================= # 3. cec_proc (lshwres -m $g_managed_system --level sys -r proc) #======================================================= g_convtabHMC78[installed_sys_proc_units]="installed_sys_proc_units" g_convtabHMC78[configurable_sys_proc_units]="configurable_sys_proc_units" g_convtabHMC78[deconfig_sys_proc_units]="deconfig_sys_proc_units" g_convtabHMC78[curr_avail_sys_proc_units]="curr_avail_sys_proc_units" g_convtabHMC78[min_proc_units_per_virtual_proc]="min_proc_units_per_virtual_proc" g_convtabHMC78[curr_free_sys_proc_units]="" # Not supported by HMC - internally computed #======================================================= # 4. lpar_sys (lssyscfg -m $g_managed_system -r lpar --filter lpar_names=$g_partition) #======================================================= g_convtabHMC78[lpar_name]="name" g_convtabHMC78[lpar_state]="state" g_convtabHMC78[lpar_id]="lpar_id" g_convtabHMC78[uuid]="uuid" g_convtabHMC78[curr_profile]="curr_profile" g_convtabHMC78[lpar_avail_priority]="lpar_avail_priority" #======================================================= # 5. lpar_prof (lssyscfg -m $g_managed_system -r prof --filter profile_names=$g_profile,lpar_names=$g_partition) #======================================================= g_convtabHMC78[prof_name]="name" g_convtabHMC78[prof_proc_mode]="proc_mode" g_convtabHMC78[prof_sharing_mode]="sharing_mode" g_convtabHMC78[prof_shared_procpool]="shared_proc_pool_name" g_convtabHMC78[prof_minimum_mem]="min_mem" g_convtabHMC78[prof_minimum_procs]="min_procs" g_convtabHMC78[prof_minimum_proc_units]="min_proc_units" g_convtabHMC78[prof_desired_mem]="desired_mem" g_convtabHMC78[prof_desired_procs]="desired_procs" g_convtabHMC78[prof_desired_proc_units]="desired_proc_units" g_convtabHMC78[prof_maximum_mem]="max_mem" g_convtabHMC78[prof_maximum_procs]="max_procs" g_convtabHMC78[prof_maximum_proc_units]="max_proc_units" #======================================================= # 6. lpar_mem (lshwres -m $g_managed_system -r mem --level lpar --filter lpar_names=$g_partition) #======================================================= g_convtabHMC78[curr_min_mem]="curr_min_mem" g_convtabHMC78[curr_mem]="curr_mem" g_convtabHMC78[curr_max_mem]="curr_max_mem" #======================================================= # 7. lpar_proc (lshwres -m $g_managed_system -r proc --level lpar --filter lpar_names=$g_partition) #======================================================= g_convtabHMC78[curr_proc_mode]="curr_proc_mode" g_convtabHMC78[curr_min_procs]="curr_min_procs" g_convtabHMC78[curr_procs]="curr_procs" g_convtabHMC78[curr_max_procs]="curr_max_procs" g_convtabHMC78[curr_min_proc_units]="curr_min_proc_units" g_convtabHMC78[curr_proc_units]="curr_proc_units" g_convtabHMC78[curr_max_proc_units]="curr_max_proc_units" #======================================================= # 8. lpar_proc_procpool (lshwres -m $g_managed_system -r procpool --filter pool_names=$g_shared_proc_pool) #======================================================= g_convtabHMC78[procpool_name]="name" g_convtabHMC78[max_pool_proc_units]="max_pool_proc_units" g_convtabHMC78[curr_free_pool_proc_units]="" # Not supported by HMC - internally computed g_convtabHMC78[curr_reserved_pool_proc_units]="curr_reserved_pool_proc_units" #======================================================= # 9. trial_mem (lscod -t cap -m $g_managed_system -c trial -r mem) #======================================================= g_convtabHMC78[mem_trial_state]="mem_trial_state" g_convtabHMC78[activated_trial_mem]="activated_trial_mem" g_convtabHMC78[mem_trial_days_left]="mem_trial_days_left" g_convtabHMC78[mem_trial_hours_left]="mem_trial_hours_left" #======================================================= # 10. trial_proc (lscod -t cap -m $g_managed_system -c trial -r proc) #======================================================= g_convtabHMC78[proc_trial_state]="proc_trial_state" g_convtabHMC78[activated_trial_procs]="activated_trial_procs" g_convtabHMC78[proc_trial_days_left]="proc_trial_days_left" g_convtabHMC78[proc_trial_hours_left]="proc_trial_hours_left" #======================================================= # 11. onoff_mem (lscod -t cap -m $g_managed_system -c onoff -r mem) #======================================================= g_convtabHMC78[mem_onoff_state]="mem_onoff_state" g_convtabHMC78[activated_onoff_mem]="activated_onoff_mem" g_convtabHMC78[avail_mem_for_onoff]="avail_mem_for_onoff" g_convtabHMC78[unreturned_onoff_mem]="unreturned_onoff_mem" g_convtabHMC78[onoff_request_mem_days_left]="onoff_request_mem_days_left" g_convtabHMC78[onoff_mem_day_hours_left]="onoff_mem_day_hours_left" g_convtabHMC78[onoff_mem_days_avail]="onoff_mem_days_avail" #======================================================= # 12. onoff_proc (lscod -t cap -m $g_managed_system -c onoff -r proc) #======================================================= g_convtabHMC78[proc_onoff_state]="proc_onoff_state" g_convtabHMC78[activated_onoff_procs]="activated_onoff_procs" g_convtabHMC78[avail_procs_for_onoff]="avail_procs_for_onoff" g_convtabHMC78[unreturned_onoff_procs]="unreturned_onoff_procs" g_convtabHMC78[onoff_request_proc_days_left]="onoff_request_proc_days_left" g_convtabHMC78[onoff_proc_day_hours_left]="onoff_proc_day_hours_left" g_convtabHMC78[onoff_proc_days_avail]="onoff_proc_days_avail" #======================================================= # 13. epcod_pool (lscodpool -p $g_enterprise_pool --level pool) #======================================================= g_convtabHMC78[codpool_name]="name" g_convtabHMC78[mobile_state]="state" g_convtabHMC78[master_mc_name]="master_mc_name" g_convtabHMC78[backup_master_mc_name]="backup_master_mc_name" g_convtabHMC78[mobile_mem]="mobile_mem" g_convtabHMC78[avail_mobile_mem]="avail_mobile_mem" g_convtabHMC78[unreturned_mobile_mem]="unreturned_mobile_mem" g_convtabHMC78[mobile_procs]="mobile_procs" g_convtabHMC78[avail_mobile_procs]="avail_mobile_procs" g_convtabHMC78[unreturned_mobile_procs]="unreturned_mobile_procs" #======================================================= # 14. epcod_sys (lscodpool -p $g_enterprise_pool --level sys --filter names=$g_managed_system) #======================================================= g_convtabHMC78[codpool_sys_names]="" # Not supported by HMC - internally computed g_convtabHMC78[sys_mobile_mem]="mobile_mem" g_convtabHMC78[sys_unreturned_mobile_mem]="unreturned_mobile_mem" g_convtabHMC78[sys_inactive_mem]="inactive_mem" g_convtabHMC78[sys_mobile_procs]="mobile_procs" g_convtabHMC78[sys_unreturned_mobile_procs]="unreturned_mobile_procs" g_convtabHMC78[sys_inactive_procs]="inactive_procs" #======================================================= # 15. lpar_cspp (lshwres -m $g_managed_system -r proc --level lpar --filter lpar_names=$g_partition) #======================================================= g_convtabHMC78[curr_shared_proc_pool_name]="curr_shared_proc_pool_name" #======================================================= # Return codes #======================================================= typeset -ri RC_SUCCESS=0 typeset -ri RC_FAILURE=1 typeset -ri RC_PARAM_ERROR=1 typeset -ri RC_PING_ERROR=2 typeset -ri RC_SSH_ERROR=3 typeset -ri RC_REM_RES_BUSY_ERROR=4 typeset -ri RC_REM_CEC_BUSY_ERROR=5 typeset -ri RC_REM_NOT_ENOUGH_RES_ERROR=6 typeset -ri RC_REM_OTHER_ERROR=7 typeset -ri RC_CEC_NOT_FOUND=8 #======================================================= # HMC version to support cross HMC #======================================================= typeset -ri CROSS_HMC_VERSION=85 #======================================================= # Dspmsg codes #======================================================= typeset ROHA_SET=38 typeset ROHA_MSGS="scripts.cat" #======================================================= # Global variables #======================================================= typeset g_operation="" typeset g_hmc_list="" typeset g_partition="" typeset g_local_partition="" typeset g_profile="" typeset g_local_profile="" typeset g_managed_system="" typeset g_local_managed_system="" typeset g_shared_proc_pool="" typeset g_local_shared_processor_pool="" typeset g_enterprise_pool="" typeset g_local_enterprise_pool="" typeset g_resource="" typeset g_safe_option=0 typeset g_running_lpars_list="" typeset g_not_act_lpars_list="" typeset -i g_force=0 typeset -i g_timeout=0 typeset -i g_memory=0 typeset -i g_quantity=0 typeset -F4 g_proc_units=0.00 typeset g_attributes="" typeset -i g_duration=-1 typeset -i g_labels=0 typeset -i g_enable_timeout=0 typeset -i g_enable_update_hmc=0 typeset -i g_epcod_modify_operation=0 #======================================================= # HMC functions # # The function is written in a string and will be copied # over ssh to the HMC to be executed in the HMC env. # This allows to avoid many ssh operations in case of # loops on HMC commands that cannot be avoided # # This require several special coding rules # Use \$ and \" if they are interpreted at HMC level. # Use $ and " not escaped if they are interpreted in current env when string is built # Use semicolon at end of each line (except for do and then) as the function string will be inlined #======================================================= #======================================================= # Name: HMCEXEC_managed_system_to_enterprise_pool # # Description: # Finds the EPCoD pool associated to a managed system # First need to list all EPCoD pools known by the HMC # Then for each pool, check if the managed system is # in the list of managed system for this pool # # All unexpected behavior needs to be reported to be logged # HMC commands executed and their return code handling : # (once) : lscodpool --level pool -F name # - success : we can pursue, looping on the discovered pools # - any error : return from the function with an error state and propagate the error message # (multiple) : lscodpool --level sys -p [pool] --filter [names|mtms]=[sys_name] -F name # - success : the correct pool is found, we can exit with success # - error with HSCL908C : the managed system is not in this pool, don't propagate this error and try next pool # - any other error : return from the function with an error state and propagate the error message # About HSCL908C agregated HSCL908C codes : # If all lscodpool --level sys ... commands in the loop returns which message : # HSCL908C Managed system [sys_name] is not in Power enterprise pool [pool_name]. # Then we agregate these HSCL908C messages to a single HSCL908C message stating that no # Power enterprise pool on this HMC knows the Managed system : # HSCL908C (SystemMirror agregated HSCL908C codes) Managed system [sys_name] is not in any Power enterprise pool known by the HMC # # Arguments: $1 [IN] Filter type to query with lscodpool (describes $2 format) : # Value can be "mtms" if $2 is like tttt-mmmm*ssss (machine type / model / serial number) # or "names" if $2 is the real managed_system name # $2 [IN] Either real managed system name or managed system mtms depending on $1 # # Environment: (Not escaped so they are interpreted at string initialization with current env values) # RC_SUCCESS # RC_FAILURE # # Output : In case of error (different from HSCL908C) : error message from HMC # In case of HSCL908C for all lscodpool in the loop : agregated HSCL908C message # In case of success : Enterprise pool name # # Returns: RC_SUCCESS # RC_FAILURE # #======================================================= typeset func_HMCEXEC_managed_system_to_enterprise_pool=" function HMCEXEC_managed_system_to_enterprise_pool { typeset ms_filter=\$1; typeset sys_name=\$2; typeset res=\"\"; typeset -i rc=0; res=\$(LC_ALL=C lscodpool --level pool -F name); rc=\$?; if (( \$rc != $RC_SUCCESS )) || [[ \$res == \"No results were found.\" ]] ; then echo \$res; return \$rc; fi; for pool in \$res ; do res=\$(lscodpool --level sys -p \$pool --filter \$ms_filter=\$sys_name -F name); rc=\$?; if (( \$rc != $RC_SUCCESS )) && [[ \$(echo \$res | LC_ALL=C grep -v \"^HSCL908C\") != \"\" ]] ; then echo \$res; return \$rc; fi; if (( \$rc == $RC_SUCCESS )) ; then echo \$pool; return $RC_SUCCESS; fi; done; echo \"HSCL908C (SystemMirror agregated HSCL908C codes) Managed system \$sys_name is not in any Power enterprise pool known by the HMC\"; return $RC_FAILURE; }" #======================================================= # Minimize function to avoid extra data on ssh # This removes all extra spaces and newlines #======================================================= func_HMCEXEC_managed_system_to_enterprise_pool=$(echo $func_HMCEXEC_managed_system_to_enterprise_pool) #======================================================= # Export environment #======================================================= PROGNAME=${0##*/} export PATH="$(/usr/es/sbin/cluster/utilities/cl_get_path all)" eval export $(cllsparam -x) [[ ${VERBOSE_LOGGING:-} == high ]] && set -x : version=@(#) 64438b3 43haes/usr/sbin/cluster/events/utils/clhmccmd.sh, 726, 2147A_aha726, Oct 13 2021 08:38 AM #======================================================= : Parse and check command line arguments #======================================================= parse_cmd_line "${@:-}" ; rc=$? (( $rc > 0 )) && exit $rc #======================================================= : Execute operation $g_operation #======================================================= case $g_operation in "query") process_query rc=$? ;; "change") process_change rc=$? ;; "acquire") process_acquire rc=$? ;; "release") process_release rc=$? ;; "halt") process_halt rc=$? ;; esac (( $rc > 0 )) && exit $rc exit 0