User Tools

Site Tools


aix:script_lsseas

List SEA VIOS

#!/usr/bin/ksh
# Program name: lsseas
# Purpose: display details and informations about Shared Ethernet Adapters
# Author: Benoit CREAU http://www.chmod666.org
# Contact: benoit.creau@chmod666.org
# Disclaimer: This programm is provided "as is". please contact me if you found bugs. Use it at you own risks
# Last update:  Feb 28, 2015
# Version: 0.1a
# License :
# This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
# To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send
# a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
#
# uncomment to debug
# set -x
# Changelog
# + 030315 Add case for more than 9 vlan per virtual adapters
# + 030315 Display ioslevel on first line
# + 030315 Sort vlan id (in all cases)
# + 030315 Changing coloring for backup
# + 030415 Reduced number of chars in VIRTUAL ADAPTERS section
# + 030415 Dynamically count vlan chars and add to printf command
# ~ 090315 Modify for duplicate vlan ids
# + 090315 Adding option -b for buffers, waring if max allocated = max
# ~ 100815 Changing f_phy_entstat_info for SRIOV adapter support
# ~ 100815 Changing f_veth_adapter_entstat_info on older hardware there is not vswitch mode printing "N/A" in this case
# ~ 091215 Changing cut_entstat to match vios 2.2.4.10 outpout for control channel
# + 040116 Adding -s option to specify sea adapter ( display only one sea)
# + 040116 Adding -t option to specify vswitch (display only one vswitch)
# ~ 040116 Bug correction for LHEA adapters

# All functions are named f_function.
# All variables are named v_variable.
# All coloring variable are begining with c.

# This script must be run on a Virtual I/O Server only.
# You have to be root to run the script.

# Function f_sort_a_numbered_line
# Purpose : Sort a line
function f_sort_a_numbered_line {
  v_line="$1"
  v_delim="$2"
  echo ${v_line} | tr "${v_delim}" '\n' | sort -un | tr '\n' "${v_delim}"
}

# Function f_norm
# Purpose : Remove trailing and heading space, and \n from a given strings
function f_norm {
  v_string_to_norm="$1"
  echo "${v_string_to_norm}" | sed 's/^[ ]*//;s/[ ]*$//g' | sed 's/\n//g'
}

# Function f_cut_entstat
# Purpose : separate entstat output in multiple file.
# Those files will be named /tmp/enstat.shared_ethernet_adapter.children_adapter.
# You can modify this function if you want to put the files in another directory.
function f_cut_entstat {
  v_ioscli_bin="/usr/ios/cli/ioscli"
  v_parent_adapter=$1
  # Parent adapter is needed, using awk -v to use shell variables in awk
  ${v_ioscli_bin} entstat -all $1 | awk -v parent_adapter="$v_parent_adapter" '{
    # All adapters in enstat are separated by "ETHERNET STATISTICS (entx)
    # This is a new adapter if $1 equals "ETHERNET and $2 equals "STATISTICS"
    if ($1 == "ETHERNET" && $2 == "STATISTICS") {
      # Replace open parenthesis by nothing
      gsub("\\(","")
      # Replace closing parenthesis by nothing
      gsub("\\)","")
      adapter=$3
      # New SEA without control channel (only if file exists) .. this part is strange I dont understand the output of entstat some have Control Adapter some not ...
      if ( v_is_new_sea == 1) {
        if( system( "[ -f /tmp/enstat."parent_adapter"."adapter" ] " )  == 0 ) {
          adapter=$3".controladapter"
          v_is_new_sea=0
        }
      }
    }
    else if ( $1 == "Control" && $2 == "Adapter:" ) {
      v_is_new_sea=1
    }
    # 2.2.4.10 new name for control channel adapters
    else if ( $1 == "Control" && $2 == "Channel" && $3 == "Adapter:") {
      v_is_new_sea=1
    }
    else {
      # The adapter statitics will be printed in an output file
      print >"/tmp/enstat."parent_adapter"."adapter
    }
  }'
}

# Function f_shared_ethernet_adapter_entstat_info
# Purpose : extract informations from entstat file for Shared Ethernet adapters.
function f_shared_ethernet_adapter_enstat_info {
  v_shared_ethernet_adapter=$1
  v_children_adapter=$2
  v_enstat_file=/tmp/enstat.${v_shared_ethernet_adapter}.${v_children_adapter}
  # Changing in IFS, we do not want space to be the IFS.
  OLD_IFS=$IFS
  IFS="|"
  # Building a ksh table with all informations about the SEA adapter.
  set -A v_table_sea_details $(awk '
    /Number of adapters:/                      { printf $NF"|" }
    /State:/                                   { printf $NF"|" }
    /Number of Times Server became Backup:/    { printf $NF"|" }
    /Number of Times Server became Primary:/   { printf $NF"|" }
    /High Availability Mode:/                  { printf $NF"|" }
    /Priority:/                                { printf $NF"|" }
    # Matching "SEA Flags set boolean for SEA Flags to 1 and go to next line.
    /SEA Flags:/                               { v_a_get_flags=1; next }
    # Matching VLAN Ids, VLAN Ids is the first line after the SEA Flags set boolean for flags to 0, set boolean for VLAN Ids to 1.
    /VLAN Ids :/                               { v_a_get_vlan_ids=1; v_a_get_flags=0 }
    # If matching something begining with < and the boolean for SEA Flags is set to 1 build the record for the flags.
    /\<*/                                      { if (v_a_get_flags == 1) {$1="";v_all_flags=v_all_flags $0} }
    # Real Side Statistics  is the first line after the Vlan Ids set boolean for vlans to 0.
    /Real Side Statistics:/                    { v_a_get_vlan_ids=0 }
    # If matching an interface after Vlan Ids flag is set to 1 build the records for the vlan ids.
    /ent[0-9]*:/                               { if (v_a_get_vlan_ids == 1) {$1=""; v_all_vlan_id=v_all_vlan_id $0} }
    END { printf v_all_vlan_id
          # Remove all > for SEA Flags
          printf "|"
          gsub(/>/,"",v_all_flags)
          printf v_all_flags
        }
  ' ${v_enstat_file})
  # Replace IFS by OLD_IFS (default one)
  IFS=$OLD_IFS
  return ${v_table_sea_details}
}

# Function f_phy_entstat_info
# Purpose : extract informations from entstat file for Real Adapters.
function f_phy_entstat_info {
  v_shared_ethernet_adapter=$1
  v_physical_adapter=$2
  v_enstat_file=/tmp/enstat.${v_shared_ethernet_adapter}.${v_physical_adapter}
  # Changing in IFS, we do not want space to be the IFS
  OLD_IFS=$IFS
  IFS="|"
  set -A v_table_phy_details $( awk -F ':' '
    # On some systems there is a space before link status ... if someone can explain
    #/^Link Status|^Physical Port Link Status/                   { v_speed_selected_found=0 ; print $NF"|"}
    # Status and Stat match additionnal HEA adapter (thanks yo Adria Pujol Boira for this one)
    /^Link Status|^Physical Port Link Stat/                   { v_speed_selected_found=0 ; print $NF"|"}
    # SRIOV Case
    /Physical Port Speed:/          { v_speed_selected_found=1 ; print "not_applicable|"$NF"|" }
    /Media Speed Selected:/         { v_speed_selected_found=1 ; print $NF }
    # For some adapter you cant select the speed field _Media Speed Selected_ will never be found
    # In this case print _not_applicable_ for selected speed
    # Hard to understand no pipe on the last print so two pipes are printed here
    /Media Speed Running:/          { if (v_speed_selected_found == 0) {
                                                                          print "not_applicable"
                                                                       }
                                      print "|"$NF"|"
                                    }
    # if 802.3ad
    /IEEE 802.3ad Port Statistics:/ { v_is_lacp=1 }
    /Actor State:/                  { v_is_actor=1 }
    /Actor System:/                 { print $NF"|"}
    # Partner after Actor
    /Partner State:/                { v_is_partn=1 ; v_is_actor=0 }
    /Partner System:/               { { print $NF"|"} }
    /Partner Port:/                 { { print $NF"|"} }
    /Synchronization:/              { if (v_is_lacp == 1 && v_is_actor == 1) { print $NF"|" }
                                      if (v_is_lacp == 1 && v_is_partn == 1) { print $NF"|" }
                                    }
  ' ${v_enstat_file})
  IFS=$OLD_IFS
  return ${v_table_phy_details}
}

# Function f_veth_adapter_entstat_info
# Purpose : extract informations from entstat file for Virtual Ethernet Adapters.
function f_veth_adapter_entstat_info {
  v_shared_ethernet_adapter=$1
  v_veth_adapter=$2
  v_enstat_file=/tmp/enstat.${v_shared_ethernet_adapter}.${v_veth_adapter}
  # Changing in IFS, we do not want space to be the IFS
  OLD_IFS=$IFS
  IFS="|"
  set -A v_table_veth_details $(awk '
    /Port VLAN ID:/                       { printf $NF"|" }
    /Switch ID:/                          { v_switch_found=0 ; v_get_vlan_tag_id=0 ; printf $NF"|" }
    # For more than 9 vlan vlans are printed on multiple lines
                                          { if (v_get_vlan_tag_id == 1 ) {
                                              for (i=1;i<=NF;i++) {
                                                v_all_vlan_tag_id=v_all_vlan_tag_id" "$i
                                              }
                                            }
                                          }
    # On some systems there is a space before Switch Mode ... if someone can explain
    /Switch Mode/                         { v_switch_found=1 ; printf $NF"|" }
    /Priority:/                           { printf $2"|"$NF"|" }
    /VLAN Tag IDs:/                       { v_get_vlan_tag_id=1 ; for (i=2;i<=NF;i++) {
                                                                    if ($i ~ /[0-9][0-9]*/ ) {
                                                                      v_all_vlan_tag_id=v_all_vlan_tag_id" "$i
                                                                    }
                                                                  }
                                          }
    # On some old box there is not vswitch mode the v_switch_found flag is here for that, adding not applicable in this case
    END { if (v_switch_found == 1 ) {
            printf v_all_vlan_tag_id
          }
          else {
            printf "N/A|"v_all_vlan_tag_id
          }
        }
  ' ${v_enstat_file})
  # Replace IFS by OLD_IFS (default one)
  IFS=$OLD_IFS
  return ${v_table_veth_details}
}

# Function f_veth_buffer_entstat_info
# Purpose : extract information from enstat file about buffers
function f_veth_buffer_entstat_info {
  v_shared_ethernet_adapter=$1
  v_veth_adapter=$2
  v_is_control_adapter=0
  v_enstat_file=/tmp/enstat.${v_shared_ethernet_adapter}.${v_veth_adapter}
  if [[ -e "${v_enstat_file}.controladapter" ]]; then
    v_is_control_adapter=1
  fi
  OLD_IFS=$IFS
  IFS="|"
  # if this is a control adapter columns 4 is control skip it
  if [[ ${v_is_control_adapter} -eq 1 ]]; then
    set -A v_table_veth_buffers $(awk '
      #No Resource Errors is at the end of the line of Max Collision Errors
      /Max Collision Errors/        { print $NF"|" }
      /Hypervisor Send Failures/    { print $NF"|" }
      /Hypervisor Receive Failures/ { print $NF"|" }
      /Receive Buffers/             { v_receive_buffers=1 }
      /Min Buffers/                 {  if (v_receive_buffers == 1 ) {
                                         v_tiny_buffers=v_tiny_buffers","$3
                                         v_smal_buffers=v_smal_buffers","$5
                                         v_medi_buffers=v_medi_buffers","$6
                                         v_larg_buffers=v_larg_buffers","$7
                                         v_huge_buffers=v_huge_buffers","$8
                                      }
                                    }
      /Max Buffers/                 {  if (v_receive_buffers == 1 ) {
                                         v_tiny_buffers=v_tiny_buffers","$3
                                         v_smal_buffers=v_smal_buffers","$5
                                         v_medi_buffers=v_medi_buffers","$6
                                         v_larg_buffers=v_larg_buffers","$7
                                         v_huge_buffers=v_huge_buffers","$8
                                      }
                                    }
      /Max Allocated/               {  if (v_receive_buffers == 1 ) {
                                         v_tiny_buffers=v_tiny_buffers","$3
                                         v_smal_buffers=v_smal_buffers","$5
                                         v_medi_buffers=v_medi_buffers","$6
                                         v_larg_buffers=v_larg_buffers","$7
                                         v_huge_buffers=v_huge_buffers","$8
                                      }
                                    }
      END { printf v_tiny_buffers"|"v_smal_buffers"|"v_medi_buffers"|"v_larg_buffers"|"v_huge_buffers }
      ' ${v_enstat_file})
  else
    set -A v_table_veth_buffers $(awk '
      #No Resource Errors is at the end of the line of Max Collision Errors
      /Max Collision Errors/        { print $NF"|" }
      /Hypervisor Send Failures/    { print $NF"|" }
      /Hypervisor Receive Failures/ { print $NF"|" }
      /Receive Buffers/             { v_receive_buffers=1 }
      /Min Buffers/                 { if (v_receive_buffers == 1 ) {
                                         v_tiny_buffers=v_tiny_buffers","$3
                                         v_smal_buffers=v_smal_buffers","$4
                                         v_medi_buffers=v_medi_buffers","$5
                                         v_larg_buffers=v_larg_buffers","$6
                                         v_huge_buffers=v_huge_buffers","$7
                                      }
                                    }
      /Max Buffers/                 { if (v_receive_buffers == 1 ) {
                                         v_tiny_buffers=v_tiny_buffers","$3
                                         v_smal_buffers=v_smal_buffers","$4
                                         v_medi_buffers=v_medi_buffers","$5
                                         v_larg_buffers=v_larg_buffers","$6
                                         v_huge_buffers=v_huge_buffers","$7
                                      }
                                    }
      /Max Allocated/               { if (v_receive_buffers == 1 ) {
                                         v_tiny_buffers=v_tiny_buffers","$3
                                         v_smal_buffers=v_smal_buffers","$4
                                         v_medi_buffers=v_medi_buffers","$5
                                         v_larg_buffers=v_larg_buffers","$6
                                         v_huge_buffers=v_huge_buffers","$7
                                      }
                                    }
    END { printf v_tiny_buffers"|"v_smal_buffers"|"v_medi_buffers"|"v_larg_buffers"|"v_huge_buffers }
    ' ${v_enstat_file})
  fi
  # Replace IFS by OLD_IFS (default one)
  IFS=$OLD_IFS
  return ${v_table_veth_buffers}
}

# Function f_get_slot_hpath
# Purpose : get slot number and what I'm calling hardware path for an adapter
function f_get_slot_hpath {
  v_adapter=$1
  v_hardware_path=$(lscfg -l ${v_adapter} | awk '{print $2}')
  v_slot=$(echo ${v_hardware_path} | cut -d "-" -f 3)
  echo ${v_slot} ${v_hardware_path}
}

# Function f_find_sea_vswitch
# Purpose : find sea for a particular vswitch name
function f_find_sea_vswitch {
  set +x
  v_vswitch=$1
  v_seas_vswitch=$(grep -i "Switch ID" /tmp/enstat* | grep ${v_vswitch} | cut -d . -f 2 | uniq)
  echo ${v_seas_vswitch}
  set -x
}

# Main
# Purpose display information about Shared Ethernet Adapters
v_color=0
v_buffers=0
v_version="0.1e 081215"

# Usage: lsseas [ options ]
#   -b, --buffers               print buffers details
#   -c, --color                 color the output for readability
#   -v, --version               print the version of lsseas
v_usage_string="Usage: lsseas [ options ]\n  -b,                   print buffers details\n  -c,                  color the output for readability\n -h,               print the help\n  -v,               print the version\n -s,                   specify a Shared Ethernet Adapter\n -t,                   specify a Virtual Switch\n"

# Get options
while getopts "cvhbs:t:" optchar ; do
  case $optchar in
    b) v_buffers=1;;
    c) v_color=1 ;;
    v) echo ${v_version}
       exit 253 ;;
    h) echo ${v_usage_string}
       echo "version : ${v_version}"
       exit 254 ;;
    s) v_choose_sea=$OPTARG ;;
    t) v_choose_vswitch=$OPTARG ;;
    *) echo "Bad option(s)"
       echo ${v_usage}
       echo ${v_usage_string}
       exit 252 ;;
  esac
done

v_ioscli_bin="/usr/ios/cli/ioscli"
v_sys_id=$(lsattr -El sys0 -a systemid | awk '{print $2}')
v_ioslevel=$(${v_ioscli_bin} ioslevel)
v_hostname=$(hostname)
echo "running lssea on ${v_hostname} | ${v_sys_id} | ioslevel ${v_ioslevel} | ${v_version}"

# Put a zero here if you do not want colors
if tty -s ; then
  esc=`printf "\033"`
  extd="${esc}[1m"
  w="${esc}[1;30m"         #gray
  r="${esc}[1;31m"         #red
  g="${esc}[1;32m"         #green
  y="${esc}[1;33m"         #yellow
  b="${esc}[1;34m"         #blue
  m="${esc}[1;35m"         #magenta/pink
  c="${esc}[1;36m"         #cyan
  i="${esc}[7m"            #inverted
  n=`printf "${esc}[m\017"` #normal
  # Did not find better to disable color ... any ideas ?
  if [[ ${v_color} -eq 0 ]]; then
    w=${n}
    r=${n}
    g=${n}
    y=${n}
    b=${n}
    c=${n}
    m=${n}
    i=${n}
  fi
fi

# For coloring debugging purpose
#all colors uncomment to check
#printf "%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n" "$w gray $n" "$r red $n" "$g green $n" "$y yellow $n" "$b blue $n" "$m magenta $n" "$c cyan $n" "$i inverted $n"
#legend
#echo "$r fail $n"
#echo "$g ok $n"
#echo "$y warning $n"

# Get all Shared Ethernet Adapters
if [[ -z ${v_choose_sea} ]] ; then
  if [[ -z ${v_choose_vswitch} ]]; then
    v_seas=$(${v_ioscli_bin} lsdev -virtual -field name description | awk '$2 == "Shared" && $3 == "Ethernet" && $4 == "Adapter" {print $1}')
  else
    #echo "choose vswitch mode"
    v_seas=$(f_find_sea_vswitch ${v_choose_vswitch})
  fi
else
  if [[ ! -z ${v_choose_sea} ]] ; then
    #echo "choose sea mode"
    v_seas=${v_choose_sea}
  fi
fi

for v_sea in ${v_seas} ; do
  # Get enstat for all Shared Ethernet Adapters
  f_cut_entstat ${v_sea}
  f_shared_ethernet_adapter_enstat_info ${v_sea} ${v_sea}
  # Here are all SEA possible states
  # INIT:     The Shared Ethernet Adapter failover protocol has just been initiated.
  # PRIMARY:  The Shared Ethernet Adapter is actively connecting traffic between the VLANs to the network.
  # BACKUP:   The Shared Ethernet Adapter is idle and not connecting traffic between the VLANs and the network.
  # RECOVERY: The primary Shared Ethernet Adapter recovered from a failure and is ready to be active again.
  # NOTIFY:   The backup Shared Ethernet Adapter detected that the primary Shared Ethernet Adapter recovered from a failure and that it needs to become idle again.
  # LIMBO:    One of the following situations is true: the physical network is not operational, the physical network's state is unknown, the Shared Ethernet Adapter cannot ping the specified remote host.
  #possible states in entstat output Disabled,Sharing,Auto,Standby
  #color state Sharing
  if [[ ${v_table_sea_details[4]} == "Sharing" || ${v_table_sea_details[4]} == "Auto" ]]; then
    # Sharing case
    if [[ ${v_table_sea_details[4]} == "Sharing" ]]; then
      case ${v_table_sea_details[1]} in
        "PRIMARY"|"BACKUP"|"LIMBO") ssc=$r ;;
        "PRIMARY_SH"|"BACKUP_SH") ssc=$g ;;
        "RECOVERY"|"NOTIFY"|"INIT") scc=$y ;;
        *) scc=$n ;;
      esac
    # Auto case
    elif [[ ${v_table_sea_details[4]} == "Auto" ]];then
      case ${v_table_sea_details[1]} in
        "LIMBO") ssc=$r ;;
        "PRIMARY") ssc=$g ;;
        "BACKUP") ssc=$y ;;
        "RECOVERY"|"NOTIFY"|"INIT") scc=$y ;;
        *) scc=$n ;;
      esac
    fi
    v_is_not_failover=0
  else
    v_is_not_failover=1
  fi

  # SEA failover case.
  if [[ ${v_is_not_failover} -eq 0 ]]; then
    v_sorted_vlans=$(f_sort_a_numbered_line "${v_table_sea_details[6]}" ' ')
    echo "+------------------------------------------------------+"
    echo "SEA : $b ${v_sea} $n"
    echo "ha_mode              : ${v_table_sea_details[4]}"
    echo "state                : $ssc${v_table_sea_details[1]}$n"
    echo "number of adapters   : ${v_table_sea_details[0]}"
    echo "become backup/primary: ${v_table_sea_details[2]}/${v_table_sea_details[3]}"
    echo "priority             : ${v_table_sea_details[5]}"
    echo "vlans                : ${v_sorted_vlans}"
    echo "flags                : ${v_table_sea_details[7]}"
    echo "+------------------------------------------------------+"
  # SEA no failover case.
  elif [[ ${v_is_not_failover} -eq 1 ]]; then
    echo "+------------------------------------------------------+"
    echo "SEA : $b ${v_sea} $n"
    echo "number of adapters   : ${v_table_sea_details[0]}"
    echo "vlans                : ${v_table_sea_details[1]}"
    echo "flags                : ${v_table_sea_details[2]}"
    echo "+------------------------------------------------------+"
  fi
  # Get all necessary attributes real_adapter,virt_adapters,pvid_adapter,ctl_chan,ha_mode,largesend,large_receive,accounting,thread
  set -A v_table_sea_attr $(${v_ioscli_bin} lsdev -dev ${v_sea} -attr real_adapter,virt_adapters,pvid_adapter,ctl_chan,ha_mode,largesend,large_receive,accounting,thread)
  # REAL ADAPTERS and ETHERCHANNEL type.
  # EtherChannel / IEEE 802.3ad Link Aggregation.
  if [[ $(${v_ioscli_bin} lsdev -dev ${v_table_sea_attr[1]} -field description | tail -1 | awk '{print $1}') == "EtherChannel" ]]; then
    v_real_adapter_type="EC"
    set -A v_table_ec_attr  $(${v_ioscli_bin} lsdev -dev ${v_table_sea_attr[1]} -attr adapter_names,hash_mode,mode,use_jumbo_frame)
    v_list_ec_adapter=$(echo "${v_table_ec_attr[1]}" | awk -F ',' '{for (i=1; i<=NF; i++) print $i}')
    echo "$i ETHERCHANNEL $n"
    printf "%-7s %-30s %-10s %-15s %-10s\n" "adapter" "phys_adapters" "mode" "hash_mode" "jumbo"
    printf "%-7s %-30s %-10s %-15s %-10s\n" "-------" "-------------" "----" "---------" "-----"
    printf "%-7s %-30s %-10s %-15s %-10s\n" ${v_table_sea_attr[1]} ${v_table_ec_attr[1]} ${v_table_ec_attr[3]} ${v_table_ec_attr[2]} ${v_table_ec_attr[4]}
    echo "$i REAL ADAPTERS $n"
    printf "%-7s %-4s %-30s %-4s %-21s %-21s %-17s %-11s %-17s %-12s %-11s\n" "adapter" "slot" "hardware_path" "link" "selected_speed" "running_speed" "actor_system" "actor_sync" "partner_system" "partner_port" "partner_sync"
    printf "%-7s %-4s %-30s %-4s %-21s %-21s %-17s %-11s %-17s %-12s %-11s\n" "-------" "----" "-------------" "----" "--------------" "-------------" "------------" "----------" "--------------" "------------" "------------"
    for v_a_ec_adapter in ${v_list_ec_adapter} ; do
      f_phy_entstat_info ${v_sea} ${v_a_ec_adapter}
      t_phy_slot_hpath=$(f_get_slot_hpath  ${v_a_ec_adapter})
      # Color case link.
      case "$(f_norm ${v_table_phy_details[0]})" in
        "Up") cl=$g;;
        *)    cl=$r;;
      esac
      # Color case synchonisation.
      case "$(f_norm ${v_table_phy_details[7]})" in
        "IN_SYNC") cps=$g;;
        *)         cps=$r;;
      esac
      case "$(f_norm ${v_table_phy_details[4]})" in
        "IN_SYNC") cas=$g;;
        *)         cas=$r;;
      esac
      # Color case speed running.
      case $(f_norm "${v_table_phy_details[2]}" | tr -s ' ' '_') in
        "Unknown") crs=$r;;
        *)         crs=$g;;
      esac

      printf "%-7s %-4s %-30s $cl%-4s$n %-21s $crs%-21s$n %-17s $cas%-11s$n %-17s %-12s $cps%-11s$n\n" "${v_a_ec_adapter}" $(echo ${t_phy_slot_hpath} | awk '{print $1}') $(echo ${t_phy_slot_hpath} | awk '{print $2}') "$(f_norm "${v_table_phy_details[0]}")" $(f_norm "${v_table_phy_details[1]}" | tr -s ' ' '_' ) $(f_norm "${v_table_phy_details[2]}" | tr -s ' ' '_') $(f_norm "${v_table_phy_details[3]}") $(f_norm "${v_table_phy_details[4]}") $(f_norm "${v_table_phy_details[5]}") $(f_norm "${v_table_phy_details[6]}") "$(f_norm ${v_table_phy_details[7]})"
    done
  # Not an etherchannel.
  else
    echo "$i REAL ADAPTERS $n"
    f_phy_entstat_info ${v_sea} ${v_table_sea_attr[1]}
    t_phy_slot_hpath=$(f_get_slot_hpath  ${v_table_sea_attr[1]})
    v_a_ec_adapter=${v_table_sea_attr[1]}
    # Color case link.
    case "$(f_norm ${v_table_phy_details[0]})" in
      "Up") cl=$g;;
      *)    cl=$r;;
    esac
    # Color case speed running.
    case $(f_norm "${v_table_phy_details[2]}" | tr -s ' ' '_') in
      "Unknown") crs=$r;;
      *)         crs=$g;;
    esac
    printf "%-7s %-4s %-30s %-4s %-21s %-21s\n" "adapter" "slot" "hardware_path" "link" "selected_speed" "running_speed"
    printf "%-7s %-4s %-30s %-4s %-21s %-21s\n" "-------" "----" "-------------" "----" "--------------" "-------------"
    printf "%-7s %-4s %-30s $cl%-4s$n %-21s $crs%-21s$n %-17s $cas%-11s$n %-17s %-12s $cps%-11s$n\n" "${v_a_ec_adapter}" $(echo ${t_phy_slot_hpath} | awk '{print $1}') $(echo ${t_phy_slot_hpath} | awk '{print $2}') "$(f_norm "${v_table_phy_details[0]}")" $(f_norm "${v_table_phy_details[1]}" | tr -s ' ' '_' ) $(f_norm "${v_table_phy_details[2]}" | tr -s ' ' '_')
  fi
  v_list_veth_adapter=$(echo "${v_table_sea_attr[2]}" | awk -F ',' '{for (i=1; i<=NF; i++) print $i}')
  # VIRTUAL ADAPTERS type.
  echo "$i VIRTUAL ADAPTERS $n"
  printf "%-7s %-4s %-30s %-8s %-6s %-13s %-15s %-7s %-14s\n" "adapter" "slot" "hardware_path" "priority" "active" "port_vlan_id" "vswitch" "mode" "vlan_tags_ids"
  printf "%-7s %-4s %-30s %-8s %-6s %-13s %-15s %-7s %-14s\n" "-------" "----" "-------------" "--------" "------" "------------" "-------" "----" "-------------"

  for v_a_veth in ${v_list_veth_adapter} ; do
    f_veth_adapter_entstat_info ${v_sea} ${v_a_veth}
    t_veth_slot_hpath=$(f_get_slot_hpath ${v_a_veth})
    # color case active
    case $(f_norm ${v_table_veth_details[1]}) in
      "False") ca=$w;;
      "True")  ca=$b;;
    esac
    v_vlan_count=$(echo $(f_sort_a_numbered_line $(echo ${v_table_veth_details[5]} | tr -s ' ' ',')))
    printf "%-7s %-4s %-30s %-8s $ca%-6s$n %-13s %-15s %-7s %-${#v_vlan_count}s\n" "${v_a_veth}" $(echo ${t_veth_slot_hpath} | awk '{print $1}')  $(echo ${t_veth_slot_hpath} | awk '{print $2}') $(f_norm ${v_table_veth_details[0]}) $(f_norm ${v_table_veth_details[1]}) $(f_norm ${v_table_veth_details[2]}) $(f_norm ${v_table_veth_details[3]}) $(f_norm ${v_table_veth_details[4]}) $(f_sort_a_numbered_line $(echo ${v_table_veth_details[5]} | tr -s ' ' ',') ' ' )
  done
  # CONTROL CHANNEL type.
  v_ctl_chan_exists=$(${v_ioscli_bin} lsdev -dev ${v_sea} -attr ctl_chan} | tail -1 | awk '$1 ~ "^ent" {print "exists"}' )
  if [[ "${v_ctl_chan_exists}" != "exists" ]]; then
    echo "$i NO CONTROL CHANNEL $n"
    # SEA Sharing or Auto without control channel
    if [[ ${v_table_sea_details[4]} == "Sharing" || ${v_table_sea_details[4]} == "Auto" ]]; then
      v_control_channel_pvid=$(grep "Control Channel PVID:" /tmp/enstat.${v_sea}.${v_sea} | awk '{print $NF}')
      echo "ctl_chan port_vlan_id: ${v_control_channel_pvid}"
    fi
  else
    echo "$i CONTROL CHANNEL $n"
    f_veth_adapter_entstat_info ${v_sea} ${v_table_sea_attr[4]}
    t_ctl_slot_hpath=$(f_get_slot_hpath ${v_table_sea_attr[4]})
    printf "%-7s %-4s %-30s %-13s %-15s\n" "adapter" "slot" "hardware_path" "port_vlan_id" "vswitch"
    printf "%-7s %-4s %-30s %-13s %-15s\n" "-------" "----" "-------------" "------------" "-------"
    printf "%-7s %-4s %-30s %-13s %-15s\n" ${v_table_sea_attr[4]} $(echo ${t_ctl_slot_hpath} | awk '{print $1}') $(echo ${t_ctl_slot_hpath} | awk '{print $2}') $(f_norm ${v_table_veth_details[0]}) $(f_norm ${v_table_veth_details[1]})
  fi
  if [[ ${v_buffers} -eq 1 ]]; then
    v_list_buff_adapter=$(echo "${v_table_sea_attr[2]}" | awk -F ',' '{for (i=1; i<=NF; i++) print $i}')
    echo "$i BUFFERS $n"
    printf "%-7s %-4s %-30s %-19s %-17s %-17s %-60s\n" "adapter" "slot" "hardware_path" "no_resources_errors" "hyp_recv_failures" "hyp_send_failures" "tiny,small,medium,large,huge (min,max,alloc)"
    printf "%-7s %-4s %-30s %-19s %-17s %-17s %-60s\n" "-------" "----" "-------------" "-------------------" "-----------------" "-----------------" "--------------------------------------------"
    for v_a_buff in ${v_list_buff_adapter} ; do
      f_veth_buffer_entstat_info ${v_sea} ${v_a_buff}
      b_veth_slot_hpath=$(f_get_slot_hpath ${v_a_buff})
      v_smal=$(f_norm ${v_table_veth_buffers[3]} | sed "s/^.\(.*\)/\1/" )
      v_tiny=$(f_norm ${v_table_veth_buffers[4]} | sed "s/^.\(.*\)/\1/" )
      v_medi=$(f_norm ${v_table_veth_buffers[5]} | sed "s/^.\(.*\)/\1/" )
      v_larg=$(f_norm ${v_table_veth_buffers[6]} | sed "s/^.\(.*\)/\1/" )
      v_huge=$(f_norm ${v_table_veth_buffers[7]} | sed "s/^.\(.*\)/\1/" )
      v_smal_min=$(echo ${v_smal} | cut -d ',' -f 1)
      v_smal_max=$(echo ${v_smal} | cut -d ',' -f 2)
      v_smal_alo=$(echo ${v_smal} | cut -d ',' -f 3)
      v_tiny_min=$(echo ${v_tiny} | cut -d ',' -f 1)
      v_tiny_max=$(echo ${v_tiny} | cut -d ',' -f 2)
      v_tiny_alo=$(echo ${v_tiny} | cut -d ',' -f 3)
      v_medi_min=$(echo ${v_medi} | cut -d ',' -f 1)
      v_medi_max=$(echo ${v_medi} | cut -d ',' -f 2)
      v_medi_alo=$(echo ${v_medi} | cut -d ',' -f 3)
      v_larg_min=$(echo ${v_larg} | cut -d ',' -f 1)
      v_larg_max=$(echo ${v_larg} | cut -d ',' -f 2)
      v_larg_alo=$(echo ${v_larg} | cut -d ',' -f 3)
      v_huge_min=$(echo ${v_larg} | cut -d ',' -f 1)
      v_huge_max=$(echo ${v_larg} | cut -d ',' -f 2)
      v_huge_alo=$(echo ${v_larg} | cut -d ',' -f 3)
      if [[ "${v_smal_max}" == "${v_smal_alo}" ]] ; then v_p_smal="${v_smal_min},$r${v_smal_max}$n,$y${v_smal_alo}$n" ; else v_p_smal="${v_smal_min},$g${v_smal_max}$n,$g${v_smal_alo}$n" ; fi
      if [[ "${v_tiny_max}" == "${v_tiny_alo}" ]] ; then v_p_tiny="${v_tiny_min},$r${v_tiny_max}$n,$y${v_tiny_alo}$n" ; else v_p_tiny="${v_tiny_min},$g${v_tiny_max}$n,$g${v_tiny_alo}$n" ; fi
      if [[ "${v_medi_max}" == "${v_medi_alo}" ]] ; then v_p_medi="${v_medi_min},$r${v_medi_max}$n,$y${v_medi_alo}$n" ; else v_p_medi="${v_medi_min},$g${v_medi_max}$n,$g${v_medi_alo}$n" ; fi
      if [[ "${v_larg_max}" == "${v_larg_alo}" ]] ; then v_p_larg="${v_larg_min},$r${v_larg_max}$n,$y${v_larg_alo}$n" ; else v_p_larg="${v_larg_min},$g${v_larg_max}$n,$g${v_larg_alo}$n" ; fi
      if [[ "${v_huge_max}" == "${v_huge_alo}" ]] ; then v_p_huge="${v_huge_min},$r${v_huge_max}$n,$y${v_huge_alo}$n" ; else v_p_huge="${v_huge_min},$g${v_huge_max}$n,$g${v_huge_alo}$n" ; fi
      printf "%-7s %-4s %-30s %-19s %-17s %-17s %-${#v_p_smal}s %-${#v_p_tiny}s %-${#v_p_medi}s %-${#v_p_larg}s %-${#v_p_huge}s\n" "${v_a_buff}" $(echo ${b_veth_slot_hpath} | awk '{print $1}')  $(echo ${b_veth_slot_hpath} | awk '{print $2}') $(f_norm ${v_table_veth_buffers[0]}) $(f_norm ${v_table_veth_buffers[1]}) $(f_norm ${v_table_veth_buffers[2]}) "${v_p_smal}" "${v_p_tiny}" "${v_p_medi}" "${v_p_larg}" "${v_p_huge}"
    done
  fi
done
aix/script_lsseas.txt · Last modified: 2021/01/05 10:41 by manu