mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-01 18:25:59 +00:00

- Moved data collection for THP from lib/bash/report_system_info.sh to lib/bash/collect_system_info.sh, so pt-summary reports THP status on the machine where samples were collected, not on the machine where an engineer examines samples.
1163 lines
45 KiB
Bash
1163 lines
45 KiB
Bash
# This program is copyright 2011 Percona Inc.
|
|
# Feedback and improvements are welcome.
|
|
#
|
|
# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free Software
|
|
# Foundation, version 2; OR the Perl Artistic License. On UNIX and similar
|
|
# systems, you can issue `man perlgpl' or `man perlartistic' to read these
|
|
# licenses.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
# Place, Suite 330, Boston, MA 02111-1307 USA.
|
|
# ###########################################################################
|
|
# report_system_info package
|
|
# ###########################################################################
|
|
|
|
# Package: report_system_info
|
|
#
|
|
|
|
set -u
|
|
|
|
# ##############################################################################
|
|
# Functions for parsing specific files and getting desired info from them.
|
|
# These are called from within report_system_summary() and are separated so
|
|
# they can be tested easily.
|
|
# ##############################################################################
|
|
|
|
# ##############################################################################
|
|
# Parse Linux's /proc/cpuinfo.
|
|
# ##############################################################################
|
|
parse_proc_cpuinfo () { local PTFUNCNAME=parse_proc_cpuinfo;
|
|
local file="$1"
|
|
# Physical processors are indicated by distinct 'physical id'. Virtual CPUs
|
|
# are indicated by paragraphs -- one per paragraph. We assume that all
|
|
# processors are identical, i.e. that there are not some processors with dual
|
|
# cores and some with quad cores.
|
|
local virtual="$(grep -c ^processor "${file}")";
|
|
local physical="$(grep 'physical id' "${file}" | sort -u | wc -l)";
|
|
local cores="$(grep 'cpu cores' "${file}" | head -n 1 | cut -d: -f2)";
|
|
|
|
# Older kernel won't have 'physical id' or 'cpu cores'.
|
|
[ "${physical}" = "0" ] && physical="${virtual}"
|
|
[ -z "${cores}" ] && cores=0
|
|
|
|
# Test for HTT; cannot trust the 'ht' flag. If physical * cores < virtual,
|
|
# then hyperthreading is in use.
|
|
cores=$((${cores} * ${physical}));
|
|
local htt=""
|
|
if [ ${cores} -gt 0 -a $cores -lt $virtual ]; then htt=yes; else htt=no; fi
|
|
|
|
name_val "Processors" "physical = ${physical}, cores = ${cores}, virtual = ${virtual}, hyperthreading = ${htt}"
|
|
|
|
awk -F: '/cpu MHz/{print $2}' "${file}" \
|
|
| sort | uniq -c > "$PT_TMPDIR/parse_proc_cpuinfo_cpu.unq"
|
|
name_val "Speeds" "$(group_concat "$PT_TMPDIR/parse_proc_cpuinfo_cpu.unq")"
|
|
|
|
awk -F: '/model name/{print $2}' "${file}" \
|
|
| sort | uniq -c > "$PT_TMPDIR/parse_proc_cpuinfo_model.unq"
|
|
name_val "Models" "$(group_concat "$PT_TMPDIR/parse_proc_cpuinfo_model.unq")"
|
|
|
|
awk -F: '/cache size/{print $2}' "${file}" \
|
|
| sort | uniq -c > "$PT_TMPDIR/parse_proc_cpuinfo_cache.unq"
|
|
name_val "Caches" "$(group_concat "$PT_TMPDIR/parse_proc_cpuinfo_cache.unq")"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse sysctl -a output on FreeBSD, and format it as CPU info. The file is the
|
|
# first argument.
|
|
# ##############################################################################
|
|
parse_sysctl_cpu_freebsd() { local PTFUNCNAME=parse_sysctl_cpu_freebsd;
|
|
local file="$1"
|
|
[ -e "$file" ] || return;
|
|
local virtual="$(awk '/hw.ncpu/{print $2}' "$file")"
|
|
name_val "Processors" "virtual = ${virtual}"
|
|
name_val "Speeds" "$(awk '/hw.clockrate/{print $2}' "$file")"
|
|
name_val "Models" "$(awk -F: '/hw.model/{print substr($2, 2)}' "$file")"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse sysctl -a output on NetBSD.
|
|
# ##############################################################################
|
|
parse_sysctl_cpu_netbsd() { local PTFUNCNAME=parse_sysctl_cpu_netbsd;
|
|
local file="$1"
|
|
|
|
# return early if they didn't pass in a file
|
|
[ -e "$file" ] || return
|
|
|
|
local virtual="$(awk '/hw.ncpu /{print $NF}' "$file")"
|
|
name_val "Processors" "virtual = ${virtual}"
|
|
#name_val "Speeds" # TODO: No clue
|
|
name_val "Models" "$(awk -F: '/hw.model/{print $3}' "$file")"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Detect cpu info on OpenBSD, and format it as CPU info
|
|
# ##############################################################################
|
|
parse_sysctl_cpu_openbsd() { local PTFUNCNAME=parse_sysctl_cpu_openbsd;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
name_val "Processors" "$(awk -F= '/hw.ncpu=/{print $2}' "$file")"
|
|
name_val "Speeds" "$(awk -F= '/hw.cpuspeed/{print $2}' "$file")"
|
|
name_val "Models" "$(awk -F= '/hw.model/{print substr($2, 1, index($2, " "))}' "$file")"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse CPU info from psrinfo -v
|
|
# ##############################################################################
|
|
parse_psrinfo_cpus() { local PTFUNCNAME=parse_psrinfo_cpus;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
name_val "Processors" "$(grep -c 'Status of .* processor' "$file")"
|
|
awk '/operates at/ {
|
|
start = index($0, " at ") + 4;
|
|
end = length($0) - start - 4
|
|
print substr($0, start, end);
|
|
}' "$file" | sort | uniq -c > "$PT_TMPDIR/parse_psrinfo_cpus.tmp"
|
|
name_val "Speeds" "$(group_concat "$PT_TMPDIR/parse_psrinfo_cpus.tmp")"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of 'free -b' plus the contents of /proc/meminfo
|
|
# ##############################################################################
|
|
parse_free_minus_b () { local PTFUNCNAME=parse_free_minus_b;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
local physical=$(awk '/Mem:/{print $3}' "${file}")
|
|
local swap_alloc=$(awk '/Swap:/{print $2}' "${file}")
|
|
local swap_used=$(awk '/Swap:/{print $3}' "${file}")
|
|
local virtual=$(shorten $(($physical + $swap_used)) 1)
|
|
|
|
name_val "Total" $(shorten $(awk '/Mem:/{print $2}' "${file}") 1)
|
|
name_val "Free" $(shorten $(awk '/Mem:/{print $4}' "${file}") 1)
|
|
name_val "Used" "physical = $(shorten ${physical} 1), swap allocated = $(shorten ${swap_alloc} 1), swap used = $(shorten ${swap_used} 1), virtual = ${virtual}"
|
|
name_val "Shared" $(shorten $(awk '/Mem:/{print $5}' "${file}") 1)
|
|
name_val "Buffers" $(shorten $(awk '/Mem:/{print $6}' "${file}") 1)
|
|
name_val "Caches" $(shorten $(awk '/Mem:/{print $7}' "${file}") 1)
|
|
name_val "Dirty" "$(awk '/Dirty:/ {print $2, $3}' "${file}")"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse FreeBSD memory info from sysctl output.
|
|
# ##############################################################################
|
|
parse_memory_sysctl_freebsd() { local PTFUNCNAME=parse_memory_sysctl_freebsd;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
local physical=$(awk '/hw.realmem:/{print $2}' "${file}")
|
|
local mem_hw=$(awk '/hw.physmem:/{print $2}' "${file}")
|
|
local mem_used=$(awk '
|
|
/hw.physmem/ { mem_hw = $2; }
|
|
/vm.stats.vm.v_inactive_count/ { mem_inactive = $2; }
|
|
/vm.stats.vm.v_cache_count/ { mem_cache = $2; }
|
|
/vm.stats.vm.v_free_count/ { mem_free = $2; }
|
|
/hw.pagesize/ { pagesize = $2; }
|
|
END {
|
|
mem_inactive *= pagesize;
|
|
mem_cache *= pagesize;
|
|
mem_free *= pagesize;
|
|
print mem_hw - mem_inactive - mem_cache - mem_free;
|
|
}
|
|
' "$file");
|
|
name_val "Total" $(shorten ${mem_hw} 1)
|
|
name_val "Virtual" $(shorten ${physical} 1)
|
|
name_val "Used" $(shorten ${mem_used} 1)
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse NetBSD memory info from sysctl output.
|
|
# ##############################################################################
|
|
parse_memory_sysctl_netbsd() { local PTFUNCNAME=parse_memory_sysctl_netbsd;
|
|
local file="$1"
|
|
local swapctl_file="$2"
|
|
|
|
[ -e "$file" -a -e "$swapctl_file" ] || return
|
|
|
|
local swap_mem="$(awk '{print $2*512}' "$swapctl_file")"
|
|
name_val "Total" $(shorten "$(awk '/hw.physmem /{print $NF}' "$file")" 1)
|
|
name_val "User" $(shorten "$(awk '/hw.usermem /{print $NF}' "$file")" 1)
|
|
name_val "Swap" $(shorten ${swap_mem} 1)
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse OpenBSD memory info from sysctl output.
|
|
# ##############################################################################
|
|
parse_memory_sysctl_openbsd() { local PTFUNCNAME=parse_memory_sysctl_openbsd;
|
|
local file="$1"
|
|
local swapctl_file="$2"
|
|
|
|
[ -e "$file" -a -e "$swapctl_file" ] || return
|
|
|
|
local swap_mem="$(awk '{print $2*512}' "$swapctl_file")"
|
|
name_val "Total" $(shorten "$(awk -F= '/hw.physmem/{print $2}' "$file")" 1)
|
|
name_val "User" $(shorten "$(awk -F= '/hw.usermem/{print $2}' "$file")" 1)
|
|
name_val "Swap" $(shorten ${swap_mem} 1)
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse memory devices from the output of 'dmidecode'.
|
|
# ##############################################################################
|
|
parse_dmidecode_mem_devices () { local PTFUNCNAME=parse_dmidecode_mem_devices;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
echo " Locator Size Speed Form Factor Type Type Detail"
|
|
echo " ========= ======== ================= ============= ============= ==========="
|
|
# Print paragraphs containing 'Memory Device\n', extract the desired bits,
|
|
# concatenate them into one long line, then format as a table. The data
|
|
# comes out in this order for each paragraph:
|
|
# $2 Size 2048 MB
|
|
# $3 Form Factor <OUT OF SPEC>
|
|
# $4 Locator DIMM1
|
|
# $5 Type <OUT OF SPEC>
|
|
# $6 Type Detail Synchronous
|
|
# $7 Speed 667 MHz (1.5 ns)
|
|
sed -e '/./{H;$!d;}' \
|
|
-e 'x;/Memory Device\n/!d;' \
|
|
-e 's/: /:/g' \
|
|
-e 's/</{/g' \
|
|
-e 's/>/}/g' \
|
|
-e 's/[ \t]*\n/\n/g' \
|
|
"${file}" \
|
|
| awk -F: '/Size|Type|Form.Factor|Type.Detail|^[\t ]+Locator|^[\t ]+Speed/{printf("|%s", $2)}/^$/{print}' \
|
|
| sed '/^$/d' \
|
|
| sed -e 's/No Module Installed/{EMPTY}/' \
|
|
| sort \
|
|
| awk -F'|' '{printf(" %-9s %-8s %-17s %-13s %-13s %-8s\n", $4, $2, $7, $3, $5, $6);}'
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse CPU cache from the output of 'dmidecode'.
|
|
# ##############################################################################
|
|
parse_dmidecode_cache_info () { local PTFUNCNAME=parse_dmidecode_cache_info;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
echo " Designation Configuration Size Associativity"
|
|
echo " ========================= ============================== ======== ======================"
|
|
sed -e '/./{H;$!d;}' \
|
|
-e 'x;/Cache Information\n/!d;' \
|
|
-e 's/: /:/g' \
|
|
-e 's/</{/g' \
|
|
-e 's/>/}/g' \
|
|
-e 's/[ \t]*\n/\n/g' \
|
|
"${file}" \
|
|
| awk -F: '/Socket Designation|Configuration|Installed Size/{printf("|%s", $2)}/^[\t ]+Associativity/{print "|" $2}' \
|
|
| awk -F'|' '{printf(" %-25s %-30s %-8s %-22s\n", $2, $3, $4, $5);}'
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of 'numactl'.
|
|
# ##############################################################################
|
|
parse_numactl () { local PTFUNCNAME=parse_numactl;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
# Print info about NUMA nodes
|
|
echo " Node Size Free CPUs"
|
|
echo " ==== ==== ==== ===="
|
|
|
|
sed -n -e 's/node /node/g' \
|
|
-e '/node[[:digit:]]/p' \
|
|
"${file}" \
|
|
| sort -r \
|
|
| awk '$1 == cnode {
|
|
if (NF > 4) { for(i=3;i<=NF;i++){printf("%s ", $i)} printf "\n" }
|
|
else { printf("%-12s", $3" "$4); }
|
|
}
|
|
$1 != cnode { cnode = $1; printf(" %-8s", $1); printf("%-12s", $3" "$4); }'
|
|
|
|
echo
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of 'ip -s link'
|
|
# ##############################################################################
|
|
parse_ip_s_link () { local PTFUNCNAME=parse_ip_s_link;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
echo " interface rx_bytes rx_packets rx_errors tx_bytes tx_packets tx_errors"
|
|
echo " ========= ========= ========== ========== ========== ========== =========="
|
|
|
|
awk "/^[1-9][0-9]*:/ {
|
|
save[\"iface\"] = substr(\$2, 1, index(\$2, \":\") - 1);
|
|
new = 1;
|
|
}
|
|
\$0 !~ /[^0-9 ]/ {
|
|
if ( new == 1 ) {
|
|
new = 0;
|
|
fuzzy_var = \$1; ${fuzzy_formula} save[\"bytes\"] = fuzzy_var;
|
|
fuzzy_var = \$2; ${fuzzy_formula} save[\"packs\"] = fuzzy_var;
|
|
fuzzy_var = \$3; ${fuzzy_formula} save[\"errs\"] = fuzzy_var;
|
|
}
|
|
else {
|
|
fuzzy_var = \$1; ${fuzzy_formula} tx_bytes = fuzzy_var;
|
|
fuzzy_var = \$2; ${fuzzy_formula} tx_packets = fuzzy_var;
|
|
fuzzy_var = \$3; ${fuzzy_formula} tx_errors = fuzzy_var;
|
|
printf \" %-8s %10.0f %10.0f %10.0f %10.0f %10.0f %10.0f\\n\", save[\"iface\"], save[\"bytes\"], save[\"packs\"], save[\"errs\"], tx_bytes, tx_packets, tx_errors;
|
|
}
|
|
}" "$file"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of 'ethtool DEVICE'
|
|
# ##############################################################################
|
|
parse_ethtool () {
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
echo " Device Speed Duplex"
|
|
echo " ========= ========= ========="
|
|
|
|
|
|
awk '
|
|
/^Settings for / {
|
|
device = substr($3, 1, index($3, ":") ? index($3, ":")-1 : length($3));
|
|
device_names[device] = device;
|
|
}
|
|
/Speed:/ { devices[device ",speed"] = $2 }
|
|
/Duplex:/ { devices[device ",duplex"] = $2 }
|
|
END {
|
|
for ( device in device_names ) {
|
|
printf(" %-10s %-10s %-10s\n",
|
|
device,
|
|
devices[device ",speed"],
|
|
devices[device ",duplex"]);
|
|
}
|
|
}
|
|
' "$file"
|
|
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of 'netstat -antp'
|
|
# ##############################################################################
|
|
parse_netstat () { local PTFUNCNAME=parse_netstat;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
echo " Connections from remote IP addresses"
|
|
awk '$1 ~ /^tcp/ && $5 ~ /^[1-9]/ {
|
|
print substr($5, 1, index($5, ":") - 1);
|
|
}' "${file}" | sort | uniq -c \
|
|
| awk "{
|
|
fuzzy_var=\$1;
|
|
${fuzzy_formula}
|
|
printf \" %-15s %5d\\n\", \$2, fuzzy_var;
|
|
}" \
|
|
| sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4
|
|
echo " Connections to local IP addresses"
|
|
awk '$1 ~ /^tcp/ && $5 ~ /^[1-9]/ {
|
|
print substr($4, 1, index($4, ":") - 1);
|
|
}' "${file}" | sort | uniq -c \
|
|
| awk "{
|
|
fuzzy_var=\$1;
|
|
${fuzzy_formula}
|
|
printf \" %-15s %5d\\n\", \$2, fuzzy_var;
|
|
}" \
|
|
| sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4
|
|
echo " Connections to top 10 local ports"
|
|
awk '$1 ~ /^tcp/ && $5 ~ /^[1-9]/ {
|
|
print substr($4, index($4, ":") + 1);
|
|
}' "${file}" | sort | uniq -c | sort -rn | head -n10 \
|
|
| awk "{
|
|
fuzzy_var=\$1;
|
|
${fuzzy_formula}
|
|
printf \" %-15s %5d\\n\", \$2, fuzzy_var;
|
|
}" | sort
|
|
echo " States of connections"
|
|
awk '$1 ~ /^tcp/ {
|
|
print $6;
|
|
}' "${file}" | sort | uniq -c | sort -rn \
|
|
| awk "{
|
|
fuzzy_var=\$1;
|
|
${fuzzy_formula}
|
|
printf \" %-15s %5d\\n\", \$2, fuzzy_var;
|
|
}" | sort
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the joined output of 'mount' and 'df -hP'. $1 = file; $2 = ostype.
|
|
# ##############################################################################
|
|
parse_filesystems () { local PTFUNCNAME=parse_filesystems;
|
|
# Filesystem names and mountpoints can be very long. We try to align things
|
|
# as nicely as possible by making columns only as wide as needed. This
|
|
# requires two passes through the file. The first pass finds the max size of
|
|
# these columns and prints out a printf spec, and the second prints out the
|
|
# file nicely aligned.
|
|
local file="$1"
|
|
local platform="$2"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
local spec="$(awk "
|
|
BEGIN {
|
|
device = 10;
|
|
fstype = 4;
|
|
options = 4;
|
|
}
|
|
/./ {
|
|
f_device = \$1;
|
|
f_fstype = \$10;
|
|
f_options = substr(\$11, 2, length(\$11) - 2);
|
|
if ( \"$2\" ~ /(Free|Open|Net)BSD/ ) {
|
|
f_fstype = substr(\$9, 2, length(\$9) - 2);
|
|
f_options = substr(\$0, index(\$0, \",\") + 2);
|
|
f_options = substr(f_options, 1, length(f_options) - 1);
|
|
}
|
|
if ( length(f_device) > device ) {
|
|
device=length(f_device);
|
|
}
|
|
if ( length(f_fstype) > fstype ) {
|
|
fstype=length(f_fstype);
|
|
}
|
|
if ( length(f_options) > options ) {
|
|
options=length(f_options);
|
|
}
|
|
}
|
|
END{
|
|
print \"%-\" device \"s %5s %4s %-\" fstype \"s %-\" options \"s %s\";
|
|
}
|
|
" "${file}")"
|
|
|
|
awk "
|
|
BEGIN {
|
|
spec=\" ${spec}\\n\";
|
|
printf spec, \"Filesystem\", \"Size\", \"Used\", \"Type\", \"Opts\", \"Mountpoint\";
|
|
}
|
|
{
|
|
f_fstype = \$10;
|
|
f_options = substr(\$11, 2, length(\$11) - 2);
|
|
if ( \"$2\" ~ /(Free|Open|Net)BSD/ ) {
|
|
f_fstype = substr(\$9, 2, length(\$9) - 2);
|
|
f_options = substr(\$0, index(\$0, \",\") + 2);
|
|
f_options = substr(f_options, 1, length(f_options) - 1);
|
|
}
|
|
printf spec, \$1, \$2, \$5, f_fstype, f_options, \$6;
|
|
}
|
|
" "${file}"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of fdisk -l, which should be in $PT_TMPDIR/percona-toolkit; there might be
|
|
# multiple fdisk -l outputs in the file.
|
|
# ##############################################################################
|
|
parse_fdisk () { local PTFUNCNAME=parse_fdisk;
|
|
local file="$1"
|
|
|
|
[ -e "$file" -a -s "$file" ] || return
|
|
|
|
awk '
|
|
BEGIN {
|
|
format="%-12s %4s %10s %10s %18s\n";
|
|
printf(format, "Device", "Type", "Start", "End", "Size");
|
|
printf(format, "============", "====", "==========", "==========", "==================");
|
|
}
|
|
/Disk.*bytes/ {
|
|
disk = substr($2, 1, length($2) - 1);
|
|
size = $5;
|
|
printf(format, disk, "Disk", "", "", size);
|
|
}
|
|
/Units/ {
|
|
units = $9;
|
|
}
|
|
/^\/dev/ {
|
|
if ( $2 == "*" ) {
|
|
start = $3;
|
|
end = $4;
|
|
}
|
|
else {
|
|
start = $2;
|
|
end = $3;
|
|
}
|
|
printf(format, $1, "Part", start, end, sprintf("%.0f", (end - start) * units));
|
|
}
|
|
' "${file}"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of lspci, and detect ethernet cards.
|
|
# ##############################################################################
|
|
parse_ethernet_controller_lspci () { local PTFUNCNAME=parse_ethernet_controller_lspci;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
grep -i ethernet "${file}" | cut -d: -f3 | while read line; do
|
|
name_val "Controller" "${line}"
|
|
done
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of "hpacucli ctrl all show config", which should be stored in
|
|
# $PT_TMPDIR/percona-toolkit
|
|
# ##############################################################################
|
|
parse_hpacucli () { local PTFUNCNAME=parse_hpacucli;
|
|
local file="$1"
|
|
[ -e "$file" ] || return
|
|
grep 'logicaldrive\|physicaldrive' "${file}"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of arcconf, which should be stored in $PT_TMPDIR/percona-toolkit
|
|
# ##############################################################################
|
|
parse_arcconf () { local PTFUNCNAME=parse_arcconf;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
local model="$(awk -F: '/Controller Model/{print $2}' "${file}")"
|
|
local chan="$(awk -F: '/Channel description/{print $2}' "${file}")"
|
|
local cache="$(awk -F: '/Installed memory/{print $2}' "${file}")"
|
|
local status="$(awk -F: '/Controller Status/{print $2}' "${file}")"
|
|
name_val "Specs" "$(echo "$model" | sed -e 's/ //'),${chan},${cache} cache,${status}"
|
|
|
|
local battery=""
|
|
if grep -q "ZMM" "$file"; then
|
|
battery="$(grep -A2 'Controller ZMM Information' "$file" \
|
|
| awk '/Status/ {s=$4}
|
|
END {printf "ZMM %s", s}')"
|
|
else
|
|
battery="$(grep -A5 'Controller Battery Info' "${file}" \
|
|
| awk '/Capacity remaining/ {c=$4}
|
|
/Status/ {s=$3}
|
|
/Time remaining/ {t=sprintf("%dd%dh%dm", $7, $9, $11)}
|
|
END {printf("%d%%, %s remaining, %s", c, t, s)}')"
|
|
fi
|
|
name_val "Battery" "${battery}"
|
|
|
|
# ###########################################################################
|
|
# Logical devices
|
|
# ###########################################################################
|
|
echo
|
|
echo " LogicalDev Size RAID Disks Stripe Status Cache"
|
|
echo " ========== ========= ==== ===== ====== ======= ======="
|
|
for dev in $(awk '/Logical device number/{print $4}' "${file}"); do
|
|
sed -n -e "/^Logical device .* ${dev}$/,/^$\|^Logical device number/p" "${file}" \
|
|
| awk '
|
|
/Logical device name/ {d=$5}
|
|
/Size/ {z=$3 " " $4}
|
|
/RAID level/ {r=$4}
|
|
/Group [0-9]/ {g++}
|
|
/Stripe-unit size/ {p=$4 " " $5}
|
|
/Status of logical/ {s=$6}
|
|
/Write-cache mode.*Ena.*write-back/ {c="On (WB)"}
|
|
/Write-cache mode.*Ena.*write-thro/ {c="On (WT)"}
|
|
/Write-cache mode.*Disabled/ {c="Off"}
|
|
END {
|
|
printf(" %-10s %-9s %4d %5d %-6s %-7s %-7s\n",
|
|
d, z, r, g, p, s, c);
|
|
}'
|
|
done
|
|
|
|
# ###########################################################################
|
|
# Physical devices
|
|
# ###########################################################################
|
|
echo
|
|
echo " PhysiclDev State Speed Vendor Model Size Cache"
|
|
echo " ========== ======= ============= ======= ============ =========== ======="
|
|
|
|
# Find the paragraph with physical devices, tabularize with assoc arrays.
|
|
local tempresult=""
|
|
sed -n -e '/Physical Device information/,/^$/p' "${file}" \
|
|
| awk -F: '
|
|
/Device #[0-9]/ {
|
|
device=substr($0, index($0, "#"));
|
|
devicenames[device]=device;
|
|
}
|
|
/Device is a/ {
|
|
devices[device ",isa"] = substr($0, index($0, "is a") + 5);
|
|
}
|
|
/State/ {
|
|
devices[device ",state"] = substr($2, 2);
|
|
}
|
|
/Transfer Speed/ {
|
|
devices[device ",speed"] = substr($2, 2);
|
|
}
|
|
/Vendor/ {
|
|
devices[device ",vendor"] = substr($2, 2);
|
|
}
|
|
/Model/ {
|
|
devices[device ",model"] = substr($2, 2);
|
|
}
|
|
/Size/ {
|
|
devices[device ",size"] = substr($2, 2);
|
|
}
|
|
/Write Cache/ {
|
|
if ( $2 ~ /Enabled .write-back./ )
|
|
devices[device ",cache"] = "On (WB)";
|
|
else
|
|
if ( $2 ~ /Enabled .write-th/ )
|
|
devices[device ",cache"] = "On (WT)";
|
|
else
|
|
devices[device ",cache"] = "Off";
|
|
}
|
|
END {
|
|
for ( device in devicenames ) {
|
|
if ( devices[device ",isa"] ~ /Hard drive/ ) {
|
|
printf(" %-10s %-7s %-13s %-7s %-12s %-11s %-7s\n",
|
|
devices[device ",isa"],
|
|
devices[device ",state"],
|
|
devices[device ",speed"],
|
|
devices[device ",vendor"],
|
|
devices[device ",model"],
|
|
devices[device ",size"],
|
|
devices[device ",cache"]);
|
|
}
|
|
}
|
|
}'
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of "lsiutil -i -s".
|
|
# ##############################################################################
|
|
# TODO This isn't used anywhere
|
|
parse_fusionmpt_lsiutil () { local PTFUNCNAME=parse_fusionmpt_lsiutil;
|
|
local file="$1"
|
|
echo
|
|
awk '/LSI.*Firmware/ { print " ", $0 }' "${file}"
|
|
grep . "${file}" | sed -n -e '/B___T___L/,$ {s/^/ /; p}'
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of MegaCli64 -AdpAllInfo -aALL
|
|
# ##############################################################################
|
|
# TODO why aren't we printing the latter half?
|
|
parse_lsi_megaraid_adapter_info () { local PTFUNCNAME=parse_lsi_megaraid_adapter_info;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
local name="$(awk -F: '/Product Name/{print substr($2, 2)}' "${file}")";
|
|
local int=$(awk '/Host Interface/{print $4}' "${file}");
|
|
local prt=$(awk '/Number of Backend Port/{print $5}' "${file}");
|
|
local bbu=$(awk '/^BBU :/{print $3}' "${file}");
|
|
local mem=$(awk '/Memory Size/{print $4}' "${file}");
|
|
local vdr=$(awk '/Virtual Drives/{print $4}' "${file}");
|
|
local dvd=$(awk '/Degraded/{print $3}' "${file}");
|
|
local phy=$(awk '/^ Disks/{print $3}' "${file}");
|
|
local crd=$(awk '/Critical Disks/{print $4}' "${file}");
|
|
local fad=$(awk '/Failed Disks/{print $4}' "${file}");
|
|
|
|
name_val "Model" "${name}, ${int} interface, ${prt} ports"
|
|
name_val "Cache" "${mem} Memory, BBU ${bbu}"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse the output of
|
|
# /opt/MegaRAID/MegaCli/MegaCli64 -AdpBbuCmd -GetBbuStatus -aALL
|
|
# ##############################################################################
|
|
parse_lsi_megaraid_bbu_status () { local PTFUNCNAME=parse_lsi_megaraid_bbu_status;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
local charge=$(awk '/Relative State/{print $5}' "${file}");
|
|
local temp=$(awk '/^Temperature/{print $2}' "${file}");
|
|
local soh=$(awk '/isSOHGood:/{print $2}' "${file}");
|
|
name_val "BBU" "${charge}% Charged, Temperature ${temp}C, isSOHGood=${soh}"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Reports the output of lvs. Additionally, if the second argument is a file
|
|
# that contains the output of 'vgs -o vg_name,vg_size,vg_free', appends the
|
|
# total and free space available to each volume.
|
|
# ##############################################################################
|
|
format_lvs () { local PTFUNCNAME=format_lvs;
|
|
local file="$1"
|
|
if [ -e "$file" ]; then
|
|
grep -v "open failed" "$file"
|
|
else
|
|
echo "Unable to collect information";
|
|
fi
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse physical devices from the output of
|
|
# /opt/MegaRAID/MegaCli/MegaCli64 -LdPdInfo -aALL
|
|
# OR, it will also work with the output of
|
|
# /opt/MegaRAID/MegaCli/MegaCli64 -PDList -aALL
|
|
# ##############################################################################
|
|
parse_lsi_megaraid_devices () { local PTFUNCNAME=parse_lsi_megaraid_devices;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
echo
|
|
echo " PhysiclDev Type State Errors Vendor Model Size"
|
|
echo " ========== ==== ======= ====== ======= ============ ==========="
|
|
for dev in $(awk '/Device Id/{print $3}' "${file}"); do
|
|
sed -e '/./{H;$!d;}' -e "x;/Device Id: ${dev}/!d;" "${file}" \
|
|
| awk '
|
|
/Media Type/ {d=substr($0, index($0, ":") + 2)}
|
|
/PD Type/ {t=$3}
|
|
/Firmware state/ {s=$3}
|
|
/Media Error Count/ {me=$4}
|
|
/Other Error Count/ {oe=$4}
|
|
/Predictive Failure Count/ {pe=$4}
|
|
/Inquiry Data/ {v=$3; m=$4;}
|
|
/Raw Size/ {z=$3}
|
|
END {
|
|
printf(" %-10s %-4s %-7s %6s %-7s %-12s %-7s\n",
|
|
substr(d, 1, 10), t, s, me "/" oe "/" pe, v, m, z);
|
|
}'
|
|
done
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Parse virtual devices from the output of
|
|
# /opt/MegaRAID/MegaCli/MegaCli64 -LdPdInfo -aALL
|
|
# OR, it will also work with the output of
|
|
# /opt/MegaRAID/MegaCli/MegaCli64 -LDInfo -Lall -aAll
|
|
# ##############################################################################
|
|
parse_lsi_megaraid_virtual_devices () { local PTFUNCNAME=parse_lsi_megaraid_virtual_devices;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
# Somewhere on the Internet, I found the following guide to understanding the
|
|
# RAID level, but I don't know the source anymore.
|
|
# Primary-0, Secondary-0, RAID Level Qualifier-0 = 0
|
|
# Primary-1, Secondary-0, RAID Level Qualifier-0 = 1
|
|
# Primary-5, Secondary-0, RAID Level Qualifier-3 = 5
|
|
# Primary-1, Secondary-3, RAID Level Qualifier-0 = 10
|
|
# I am not sure if this is always correct or not (it seems correct). The
|
|
# terminology MegaRAID uses is not clear to me, and isn't documented that I
|
|
# am aware of. Anyone who can clarify the above, please contact me.
|
|
echo
|
|
echo " VirtualDev Size RAID Level Disks SpnDpth Stripe Status Cache"
|
|
echo " ========== ========= ========== ===== ======= ====== ======= ========="
|
|
awk '
|
|
/^Virtual (Drive|Disk):/ {
|
|
device = $3;
|
|
devicenames[device] = device;
|
|
}
|
|
/Number Of Drives/ {
|
|
devices[device ",numdisks"] = substr($0, index($0, ":") + 1);
|
|
}
|
|
/^Name/ {
|
|
devices[device ",name"] = substr($0, index($0, ":") + 1) > "" ? substr($0, index($0, ":") + 1) : "(no name)";
|
|
}
|
|
/RAID Level/ {
|
|
devices[device ",primary"] = substr($3, index($3, "-") + 1, 1);
|
|
devices[device ",secondary"] = substr($4, index($4, "-") + 1, 1);
|
|
devices[device ",qualifier"] = substr($NF, index($NF, "-") + 1, 1);
|
|
}
|
|
/Span Depth/ {
|
|
devices[device ",spandepth"] = substr($2, index($2, ":") + 1);
|
|
}
|
|
/Number of Spans/ {
|
|
devices[device ",numspans"] = $4;
|
|
}
|
|
/^Size/ {
|
|
devices[device ",size"] = substr($0, index($0, ":") + 1);
|
|
}
|
|
/^State/ {
|
|
devices[device ",state"] = substr($0, index($0, ":") + 2);
|
|
}
|
|
/^Stripe? Size/ {
|
|
devices[device ",stripe"] = substr($0, index($0, ":") + 1);
|
|
}
|
|
/^Current Cache Policy/ {
|
|
devices[device ",wpolicy"] = $4 ~ /WriteBack/ ? "WB" : "WT";
|
|
devices[device ",rpolicy"] = $5 ~ /ReadAheadNone/ ? "no RA" : "RA";
|
|
}
|
|
END {
|
|
for ( device in devicenames ) {
|
|
raid = 0;
|
|
if ( devices[device ",primary"] == 1 ) {
|
|
raid = 1;
|
|
if ( devices[device ",secondary"] == 3 ) {
|
|
raid = 10;
|
|
}
|
|
}
|
|
else {
|
|
if ( devices[device ",primary"] == 5 ) {
|
|
raid = 5;
|
|
}
|
|
}
|
|
printf(" %-10s %-9s %-10s %5d %7s %6s %-7s %s\n",
|
|
device devices[device ",name"],
|
|
devices[device ",size"],
|
|
raid " (" devices[device ",primary"] "-" devices[device ",secondary"] "-" devices[device ",qualifier"] ")",
|
|
devices[device ",numdisks"],
|
|
devices[device ",spandepth"] "-" devices[device ",numspans"],
|
|
devices[device ",stripe"], devices[device ",state"],
|
|
devices[device ",wpolicy"] ", " devices[device ",rpolicy"]);
|
|
}
|
|
}' "${file}"
|
|
}
|
|
|
|
# ##############################################################################
|
|
# Simplifies vmstat and aligns it nicely. We don't need the memory stats, the
|
|
# system activity is enough.
|
|
# ##############################################################################
|
|
format_vmstat () { local PTFUNCNAME=format_vmstat;
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
awk "
|
|
BEGIN {
|
|
format = \" %2s %2s %4s %4s %5s %5s %6s %6s %3s %3s %3s %3s %3s\n\";
|
|
}
|
|
/procs/ {
|
|
print \" procs ---swap-- -----io---- ---system---- --------cpu--------\";
|
|
}
|
|
/bo/ {
|
|
printf format, \"r\", \"b\", \"si\", \"so\", \"bi\", \"bo\", \"ir\", \"cs\", \"us\", \"sy\", \"il\", \"wa\", \"st\";
|
|
}
|
|
\$0 !~ /r/ {
|
|
fuzzy_var = \$1; ${fuzzy_formula} r = fuzzy_var;
|
|
fuzzy_var = \$2; ${fuzzy_formula} b = fuzzy_var;
|
|
fuzzy_var = \$7; ${fuzzy_formula} si = fuzzy_var;
|
|
fuzzy_var = \$8; ${fuzzy_formula} so = fuzzy_var;
|
|
fuzzy_var = \$9; ${fuzzy_formula} bi = fuzzy_var;
|
|
fuzzy_var = \$10; ${fuzzy_formula} bo = fuzzy_var;
|
|
fuzzy_var = \$11; ${fuzzy_formula} ir = fuzzy_var;
|
|
fuzzy_var = \$12; ${fuzzy_formula} cs = fuzzy_var;
|
|
fuzzy_var = \$13; us = fuzzy_var;
|
|
fuzzy_var = \$14; sy = fuzzy_var;
|
|
fuzzy_var = \$15; il = fuzzy_var;
|
|
fuzzy_var = \$16; wa = fuzzy_var;
|
|
fuzzy_var = \$17; st = fuzzy_var;
|
|
printf format, r, b, si, so, bi, bo, ir, cs, us, sy, il, wa, st;
|
|
}
|
|
" "${file}"
|
|
}
|
|
|
|
processes_section () { local PTFUNCNAME=processes_section;
|
|
local top_process_file="$1"
|
|
local notable_procs_file="$2"
|
|
local vmstat_file="$3"
|
|
local platform="$4"
|
|
|
|
section "Top Processes"
|
|
cat "$top_process_file"
|
|
section "Notable Processes"
|
|
cat "$notable_procs_file"
|
|
if [ -e "$vmstat_file" ]; then
|
|
section "Simplified and fuzzy rounded vmstat (wait please)"
|
|
wait # For the process we forked that was gathering vmstat samples
|
|
if [ "${platform}" = "Linux" ]; then
|
|
format_vmstat "$vmstat_file"
|
|
else
|
|
# TODO: simplify/format for other platforms
|
|
cat "$vmstat_file"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
section_Processor () {
|
|
local platform="$1"
|
|
local data_dir="$2"
|
|
|
|
section "Processor"
|
|
|
|
if [ -e "$data_dir/proc_cpuinfo_copy" ]; then
|
|
parse_proc_cpuinfo "$data_dir/proc_cpuinfo_copy"
|
|
elif [ "${platform}" = "FreeBSD" ]; then
|
|
parse_sysctl_cpu_freebsd "$data_dir/sysctl"
|
|
elif [ "${platform}" = "NetBSD" ]; then
|
|
parse_sysctl_cpu_netbsd "$data_dir/sysctl"
|
|
elif [ "${platform}" = "OpenBSD" ]; then
|
|
parse_sysctl_cpu_openbsd "$data_dir/sysctl"
|
|
elif [ "${platform}" = "SunOS" ]; then
|
|
parse_psrinfo_cpus "$data_dir/psrinfo_minus_v"
|
|
# TODO: prtconf -v actually prints the CPU model name etc.
|
|
fi
|
|
|
|
if [ -s "$data_dir/dmidecode" ]; then
|
|
parse_dmidecode_cache_info "$data_dir/dmidecode"
|
|
fi
|
|
}
|
|
|
|
section_Memory () {
|
|
local platform="$1"
|
|
local data_dir="$2"
|
|
|
|
local name_val_len_orig=$NAME_VAL_LEN;
|
|
local NAME_VAL_LEN=14
|
|
|
|
section "Memory"
|
|
if [ "${platform}" = "Linux" ]; then
|
|
parse_free_minus_b "$data_dir/memory"
|
|
elif [ "${platform}" = "FreeBSD" ]; then
|
|
parse_memory_sysctl_freebsd "$data_dir/sysctl"
|
|
elif [ "${platform}" = "NetBSD" ]; then
|
|
parse_memory_sysctl_netbsd "$data_dir/sysctl" "$data_dir/swapctl"
|
|
elif [ "${platform}" = "OpenBSD" ]; then
|
|
parse_memory_sysctl_openbsd "$data_dir/sysctl" "$data_dir/swapctl"
|
|
elif [ "${platform}" = "SunOS" ]; then
|
|
name_val "Memory" "$(cat "$data_dir/memory")"
|
|
fi
|
|
|
|
local rss=$( get_var "rss" "$data_dir/summary" )
|
|
name_val "UsedRSS" "$(shorten ${rss} 1)"
|
|
|
|
if [ "${platform}" = "Linux" ]; then
|
|
name_val "Swappiness" "$(get_var "swappiness" "$data_dir/summary")"
|
|
name_val "DirtyPolicy" "$(get_var "dirtypolicy" "$data_dir/summary")"
|
|
local dirty_status="$(get_var "dirtystatus" "$data_dir/summary")"
|
|
if [ -n "$dirty_status" ]; then
|
|
name_val "DirtyStatus" "$dirty_status"
|
|
fi
|
|
fi
|
|
|
|
if [ -s "$data_dir/numactl" ]; then
|
|
name_val "Numa Nodes" "$(get_var "numa-available" "$data_dir/summary")"
|
|
name_val "Numa Policy" "$(get_var "numa-policy" "$data_dir/summary")"
|
|
name_val "Preferred Node" "$(get_var "numa-preferred-node" "$data_dir/summary")"
|
|
|
|
parse_numactl "$data_dir/numactl"
|
|
fi
|
|
|
|
local NAME_VAL_LEN=$name_val_len_orig;
|
|
|
|
if [ -s "$data_dir/dmidecode" ]; then
|
|
parse_dmidecode_mem_devices "$data_dir/dmidecode"
|
|
fi
|
|
}
|
|
|
|
parse_uptime () {
|
|
local file="$1"
|
|
|
|
awk ' / up / {
|
|
printf substr($0, index($0, " up ")+4 );
|
|
}
|
|
!/ up / {
|
|
printf $0;
|
|
}
|
|
' "$file"
|
|
}
|
|
|
|
report_fio_minus_a () {
|
|
local file="$1"
|
|
|
|
name_val "fio Driver" "$(get_var driver_version "$file")"
|
|
|
|
local adapters="$( get_var "adapters" "$file" )"
|
|
for adapter in $( echo $adapters | awk '{for (i=1; i<=NF; i++) print $i;}' ); do
|
|
local adapter_for_output="$(echo "$adapter" | sed 's/::[0-9]*$//' | tr ':' ' ')"
|
|
name_val "$adapter_for_output" "$(get_var "${adapter}_general" "$file")"
|
|
|
|
local modules="$(get_var "${adapter}_modules" "$file")"
|
|
for module in $( echo $modules | awk '{for (i=1; i<=NF; i++) print $i;}' ); do
|
|
local name_val_len_orig=$NAME_VAL_LEN;
|
|
local NAME_VAL_LEN=16
|
|
name_val "$module" "$(get_var "${adapter}_${module}_attached_as" "$file")"
|
|
name_val "" "$(get_var "${adapter}_${module}_general" "$file")"
|
|
name_val "" "$(get_var "${adapter}_${module}_firmware" "$file")"
|
|
name_val "" "$(get_var "${adapter}_${module}_temperature" "$file")"
|
|
name_val "" "$(get_var "${adapter}_${module}_media_status" "$file")"
|
|
if [ "$(get_var "${adapter}_${module}_rated_pbw" "$file")" ]; then
|
|
name_val "" "$(get_var "${adapter}_${module}_rated_pbw" "$file")"
|
|
fi
|
|
local NAME_VAL_LEN=$name_val_len_orig;
|
|
done
|
|
done
|
|
}
|
|
|
|
# The sum of all of the above
|
|
report_system_summary () { local PTFUNCNAME=report_system_summary;
|
|
local data_dir="$1"
|
|
|
|
section "Percona Toolkit System Summary Report"
|
|
|
|
# ########################################################################
|
|
# General date, time, load, etc
|
|
# ########################################################################
|
|
|
|
[ -e "$data_dir/summary" ] \
|
|
|| die "The data directory doesn't have a summary file, exiting."
|
|
|
|
local platform="$(get_var "platform" "$data_dir/summary")"
|
|
name_val "Date" "`date -u +'%F %T UTC'` (local TZ: `date +'%Z %z'`)"
|
|
name_val "Hostname" "$(get_var hostname "$data_dir/summary")"
|
|
name_val "Uptime" "$(parse_uptime "$data_dir/uptime")"
|
|
|
|
if [ "$(get_var "vendor" "$data_dir/summary")" ]; then
|
|
name_val "System" "$(get_var "system" "$data_dir/summary")";
|
|
name_val "Service Tag" "$(get_var "servicetag" "$data_dir/summary")";
|
|
fi
|
|
|
|
name_val "Platform" "${platform}"
|
|
local zonename="$(get_var zonename "$data_dir/summary")";
|
|
[ -n "${zonename}" ] && name_val "Zonename" "$zonename"
|
|
|
|
name_val "Release" "$(get_var "release" "$data_dir/summary")"
|
|
name_val "Kernel" "$(get_var "kernel" "$data_dir/summary")"
|
|
|
|
name_val "Architecture" "CPU = $(get_var "CPU_ARCH" "$data_dir/summary"), OS = $(get_var "OS_ARCH" "$data_dir/summary")"
|
|
|
|
local threading="$(get_var threading "$data_dir/summary")"
|
|
local compiler="$(get_var compiler "$data_dir/summary")"
|
|
[ -n "$threading" ] && name_val "Threading" "$threading"
|
|
[ -n "$compiler" ] && name_val "Compiler" "$compiler"
|
|
|
|
local getenforce="$(get_var getenforce "$data_dir/summary")"
|
|
[ -n "$getenforce" ] && name_val "SELinux" "${getenforce}";
|
|
|
|
name_val "Virtualized" "$(get_var "virt" "$data_dir/summary")"
|
|
|
|
# ########################################################################
|
|
# Processor/CPU, Memory, Swappiness, dmidecode
|
|
# ########################################################################
|
|
section_Processor "$platform" "$data_dir"
|
|
|
|
section_Memory "$platform" "$data_dir"
|
|
|
|
# ########################################################################
|
|
# Disks, RAID, Filesystems
|
|
# ########################################################################
|
|
# TODO: Add info about software RAID
|
|
|
|
if [ -s "$data_dir/fusion-io_card" ]; then
|
|
section "Fusion-io Card"
|
|
report_fio_minus_a "$data_dir/fusion-io_card"
|
|
fi
|
|
|
|
if [ -s "$data_dir/mounted_fs" ]; then
|
|
section "Mounted Filesystems"
|
|
parse_filesystems "$data_dir/mounted_fs" "${platform}"
|
|
fi
|
|
|
|
if [ "${platform}" = "Linux" ]; then
|
|
|
|
section "Disk Schedulers And Queue Size"
|
|
local disks="$( get_var "internal::disks" "$data_dir/summary" )"
|
|
for disk in $disks; do
|
|
local scheduler="$( get_var "internal::${disk}" "$data_dir/summary" )"
|
|
name_val "${disk}" "${scheduler:-"UNREADABLE"}"
|
|
done
|
|
|
|
section "Disk Partitioning"
|
|
parse_fdisk "$data_dir/partitioning"
|
|
|
|
section "Kernel Inode State"
|
|
for file in dentry-state file-nr inode-nr; do
|
|
name_val "${file}" "$(get_var "${file}" "$data_dir/summary")"
|
|
done
|
|
|
|
section "LVM Volumes"
|
|
format_lvs "$data_dir/lvs"
|
|
section "LVM Volume Groups"
|
|
format_lvs "$data_dir/vgs"
|
|
fi
|
|
|
|
section "RAID Controller"
|
|
local controller="$(get_var "raid_controller" "$data_dir/summary")"
|
|
name_val "Controller" "$controller"
|
|
local key="$(get_var "internal::raid_opt" "$data_dir/summary")"
|
|
case "$key" in
|
|
0)
|
|
# Not found
|
|
cat "$data_dir/raid-controller"
|
|
;;
|
|
1)
|
|
parse_arcconf "$data_dir/raid-controller"
|
|
;;
|
|
2)
|
|
parse_hpacucli "$data_dir/raid-controller"
|
|
;;
|
|
3)
|
|
# TODO: This is pretty bad form, but seeing how the three forms
|
|
# aren't mutually exclusive, I can't come up with a better way.
|
|
[ -e "$data_dir/lsi_megaraid_adapter_info.tmp" ] && \
|
|
parse_lsi_megaraid_adapter_info "$data_dir/lsi_megaraid_adapter_info.tmp"
|
|
[ -e "$data_dir/lsi_megaraid_bbu_status.tmp" ] && \
|
|
parse_lsi_megaraid_bbu_status "$data_dir/lsi_megaraid_bbu_status.tmp"
|
|
if [ -e "$data_dir/lsi_megaraid_devices.tmp" ]; then
|
|
parse_lsi_megaraid_virtual_devices "$data_dir/lsi_megaraid_devices.tmp"
|
|
parse_lsi_megaraid_devices "$data_dir/lsi_megaraid_devices.tmp"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
if [ "${OPT_SUMMARIZE_NETWORK}" ]; then
|
|
# #####################################################################
|
|
# Network stuff
|
|
# #####################################################################
|
|
if [ "${platform}" = "Linux" ]; then
|
|
section "Network Config"
|
|
if [ -s "$data_dir/lspci_file" ]; then
|
|
parse_ethernet_controller_lspci "$data_dir/lspci_file"
|
|
fi
|
|
if grep "net.ipv4.tcp_fin_timeout" "$data_dir/sysctl" > /dev/null 2>&1; then
|
|
name_val "FIN Timeout" "$(awk '/net.ipv4.tcp_fin_timeout/{print $NF}' "$data_dir/sysctl")"
|
|
name_val "Port Range" "$(awk '/net.ipv4.ip_local_port_range/{print $NF}' "$data_dir/sysctl")"
|
|
fi
|
|
fi
|
|
|
|
# TODO cat /proc/sys/net/ipv4/ip_conntrack_max ; it might be
|
|
# /proc/sys/net/netfilter/nf_conntrack_max or /proc/sys/net/nf_conntrack_max
|
|
# in new kernels like Fedora 12?
|
|
|
|
if [ -s "$data_dir/ip" ]; then
|
|
section "Interface Statistics"
|
|
parse_ip_s_link "$data_dir/ip"
|
|
fi
|
|
|
|
if [ -s "$data_dir/network_devices" ]; then
|
|
section "Network Devices"
|
|
parse_ethtool "$data_dir/network_devices"
|
|
fi
|
|
|
|
if [ "${platform}" = "Linux" -a -e "$data_dir/netstat" ]; then
|
|
section "Network Connections"
|
|
parse_netstat "$data_dir/netstat"
|
|
fi
|
|
fi
|
|
|
|
# ########################################################################
|
|
# Processes, load, etc
|
|
# ########################################################################
|
|
[ "$OPT_SUMMARIZE_PROCESSES" ] && processes_section \
|
|
"$data_dir/processes" \
|
|
"$data_dir/notable_procs" \
|
|
"$data_dir/vmstat" \
|
|
"$platform"
|
|
|
|
section "Memory management"
|
|
report_transparent_huge_pages "$data_dir/transparent_hugepage"
|
|
|
|
# ########################################################################
|
|
# All done. Signal the end so it's explicit.
|
|
# ########################################################################
|
|
section "The End"
|
|
}
|
|
|
|
report_transparent_huge_pages () {
|
|
local file="$1"
|
|
|
|
[ -e "$file" ] || return
|
|
|
|
if [ $(grep -cv '\[never\]' $file) = 0 ]; then
|
|
echo "Transparent huge pages are currently disabled on the system."
|
|
else
|
|
echo "Transparent huge pages are enabled."
|
|
fi
|
|
}
|
|
|
|
# ###########################################################################
|
|
# End report_system_info package
|
|
# ###########################################################################
|