import powerpc-utils-1.3.8-9.el8_5

This commit is contained in:
CentOS Sources 2022-02-01 15:13:59 -05:00 committed by Stepan Oksanichenko
parent 147605391e
commit 4e93e02826
2 changed files with 329 additions and 1 deletions

View File

@ -0,0 +1,320 @@
commit 4c6dc50d8de1a8b171675ee6b742c9f0250c28a1
Author: Scott Cheloha <cheloha@linux.ibm.com>
Date: Tue Jul 27 11:30:58 2021 -0500
lsdevinfo: optimize criteria filtering
lsdevinfo is significantly slower when a criteria filter is set with the
-q flag.
There are two culprits:
1. The criteria string given on the command line is parsed every time
we call check_criteria(). We're forking two sed(1) processes whenever
we hit that function. We hit it a lot.
2. Criteria checking runs in constant time. We call check_criteria() and
do the parsing in (1) for every relevant attribute, even if we already
have a match from a prior check_criteria() invocation.
We can fix issue (1) by parsing the criteria string once at the start
of the script. I have added a function, parse_criteria(), that parses
the $criteria string and selects an appropriate matching function.
This approach also fixes problem (2), but we first need to check
whether the user's criteria is relevant to the attributes the script
cares about before calling the matching function. We do this with
criteria_is_relevant().
The speed improvement is nice. Consider my test machine with around
thirty devices. On this machine, lsdevinfo without any options runs
in 1.35s, but with the "status=1" criteria it runs in 2.12s:
$ /usr/sbin/lsdevinfo | fgrep -c device:
29
$ command time -p /usr/sbin/lsdevinfo > /dev/null
real 1.35
user 1.42
sys 0.16
$ command time -p /usr/sbin/lsdevinfo -q status=1 > /dev/null
real 2.12
user 2.22
sys 0.30
With this patch, lsdevinfo with the "status=1" criteria now runs in
1.35s:
$ command time -p /usr/sbin/lsdevinfo -q status=1 > /dev/null
real 1.35
user 1.41
sys 0.18
This patch eliminates nearly all of the criteria-checking overhead in
the current code.
Signed-off-by: Scott Cheloha <cheloha@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/scripts/lsdevinfo b/scripts/lsdevinfo
index 1d9597b..7a3cba3 100755
--- a/scripts/lsdevinfo
+++ b/scripts/lsdevinfo
@@ -61,37 +61,113 @@ show_version()
echo "Written by: Santiago Leon <sleon@ec.ibm.com>"
}
-# check_criteria
-# Modifies $show if the the attribute in the first parameter matches the
-# criteria from the command line.
-# The operands (=, !=, and LIKE) are defined the the lsdevinfo spec.
#
-check_criteria()
+# Criteria matching boilerplate.
+#
+_class_eq() { [[ $class = $crit_rhs ]]; }
+_class_neq() { [[ $class != $crit_rhs ]]; }
+_class_like() { [[ $class =~ $crit_rhs ]]; }
+
+_driver_eq() { [[ $driver = $crit_rhs ]]; }
+_driver_neq() { [[ $driver != $crit_rhs ]]; }
+_driver_like() { [[ $driver =~ $crit_rhs ]]; }
+
+_name_eq() { [[ $name = $crit_rhs ]]; }
+_name_neq() { [[ $name != $crit_rhs ]]; }
+_name_like() { [[ $name =~ $crit_rhs ]]; }
+
+_parent_eq() { [[ $parent = $crit_rhs ]]; }
+_parent_neq() { [[ $parent != $crit_rhs ]]; }
+_parent_like() { [[ $parent =~ $crit_rhs ]]; }
+
+_physloc_eq() { [[ $physloc = $crit_rhs ]]; }
+_physloc_neq() { [[ $physloc != $crit_rhs ]]; }
+_physloc_like() { [[ $physloc =~ $crit_rhs ]]; }
+
+_prefix_eq() { [[ $prefix = $crit_rhs ]]; }
+_prefix_neq() { [[ $prefix != $crit_rhs ]]; }
+_prefix_like() { [[ $prefix =~ $crit_rhs ]]; }
+
+_status_eq() { [[ $status = $crit_rhs ]]; }
+_status_neq() { [[ $status != $crit_rhs ]]; }
+_status_like() { [[ $status =~ $crit_rhs ]]; }
+
+_subclass_eq() { [[ $subclass = $crit_rhs ]]; }
+_subclass_neq() { [[ $subclass != $crit_rhs ]]; }
+_subclass_like() { [[ $subclass =~ $crit_rhs ]]; }
+
+_type_eq() { [[ $type = $crit_rhs ]]; }
+_type_neq() { [[ $type != $crit_rhs ]]; }
+_type_like() { [[ $type =~ $crit_rhs ]]; }
+
+_uniquetype_eq() { [[ $uniquetype = $crit_rhs ]]; }
+_uniquetype_neq() { [[ $uniquetype != $crit_rhs ]]; }
+_uniquetype_like() { [[ $uniquetype =~ $crit_rhs ]]; }
+
+# Check if the attribute we're filtering on appears in the string
+# given as argument.
+criteria_is_relevant()
{
- attr=$1
- attr_val=${!attr}
+ [[ "$1" =~ "$crit_lhs" ]]
+}
+# Run the criteria-matching function.
+criteria_matches()
+{
+ $criteria_checker
+}
+
+# Select a criteria-matching function based on the $criteria string.
+parse_criteria()
+{
if [[ $criteria =~ "!=" ]] ; then
- # Pull out the operands from the criteria (everything to the left of
- # the operand, and everything on the right of the operand)
- crit_opd1=$(echo $criteria | $SED -e "s/[ ]*!=.*//")
- crit_opd2=$(echo $criteria | $SED -e "s/.*!=[ ]*//")
- # Perfom the comparison of the attribute and its value
- if [[ $crit_opd1 == $attr && $crit_opd2 != $attr_val ]]; then
- show=1
- fi
+ crit_lhs=$(echo $criteria | $SED -e "s/[ ]*!=.*//")
+ crit_rhs=$(echo $criteria | $SED -e "s/.*!=[ ]*//")
+ case "$crit_lhs" in
+ class) criteria_checker=_class_neq;;
+ driver) criteria_checker=_driver_neq;;
+ name) criteria_checker=_name_neq;;
+ parent) criteria_checker=_parent_neq;;
+ physloc) criteria_checker=_physloc_neq;;
+ prefix) criteria_checker=_prefix_neq;;
+ status) criteria_checker=_status_neq;;
+ subclass) criteria_checker=_subclass_neq;;
+ type) criteria_checker=_type_neq;;
+ uniquetype) criteria_checker=_uniquetype_neq;;
+ *) criteria_checker=false;;
+ esac
elif [[ $criteria =~ "=" ]]; then
- crit_opd1=$(echo $criteria | $SED -e "s/[ ]*=.*//")
- crit_opd2=$(echo $criteria | $SED -e "s/.*=[ ]*//")
- if [[ $crit_opd1 == $attr && $crit_opd2 == $attr_val ]]; then
- show=1
- fi
+ crit_lhs=$(echo $criteria | $SED -e "s/[ ]*=.*//")
+ crit_rhs=$(echo $criteria | $SED -e "s/.*=[ ]*//")
+ case "$crit_lhs" in
+ class) criteria_checker=_class_eq;;
+ driver) criteria_checker=_driver_eq;;
+ name) criteria_checker=_name_eq;;
+ parent) criteria_checker=_parent_eq;;
+ physloc) criteria_checker=_physloc_eq;;
+ prefix) criteria_checker=_prefix_eq;;
+ status) criteria_checker=_status_eq;;
+ subclass) criteria_checker=_subclass_eq;;
+ type) criteria_checker=_type_eq;;
+ uniquetype) criteria_checker=_uniquetype_eq;;
+ *) criteria_checker=false;;
+ esac
elif [[ $criteria =~ " LIKE " ]]; then
- crit_opd1=$(echo $criteria | $SED -e "s/[ ]*LIKE.*//")
- crit_opd2=$(echo $criteria | $SED -e "s/.*LIKE[ ]*//")
- if [[ $crit_opd1 == $attr && $attr_val =~ $crit_opd2 ]]; then
- show=1
- fi
+ crit_lhs=$(echo $criteria | $SED -e "s/[ ]*LIKE.*//")
+ crit_rhs=$(echo $criteria | $SED -e "s/.*LIKE[ ]*//")
+ case "$crit_lhs" in
+ class) criteria_checker=_class_like;;
+ driver) criteria_checker=_driver_like;;
+ name) criteria_checker=_name_like;;
+ parent) criteria_checker=_parent_like;;
+ physloc) criteria_checker=_physloc_like;;
+ prefix) criteria_checker=_prefix_like;;
+ status) criteria_checker=_status_like;;
+ subclass) criteria_checker=_subclass_like;;
+ type) criteria_checker=_type_like;;
+ uniquetype) criteria_checker=_uniquetype_like;;
+ *) criteria_checker=false;;
+ esac
else
echo "Criteria must have =, !=, or LIKE operand. Exiting."
exit 1
@@ -124,6 +200,8 @@ recursive=0
# default: display all devices
criteria=""
+criteria_checker=:
+crit_lhs=""
# default: display all attributes
format=""
@@ -162,6 +240,12 @@ if [[ $criteria =~ " AND " ]] ; then
exit 1
fi
+# If we have a criteria string, parse it and choose a criteria
+# matching function.
+if [[ -n "$criteria" ]]; then
+ parse_criteria
+fi
+
# Fill variables for the two display formats (regular and comma-separated) so
# we can print the output in a single place.
if [[ $comma_sep -eq 0 ]]; then
@@ -184,15 +268,10 @@ show_eth ()
# if there is a criteria in the command line, check if this device matches
if [[ $criteria != "" ]] ; then
show=0
- check_criteria "name"
- check_criteria "physloc"
- check_criteria "uniquetype"
- check_criteria "class"
- check_criteria "subclass"
- check_criteria "type"
- check_criteria "prefix"
- check_criteria "driver"
- check_criteria "status"
+ attrs="name physloc uniquetype class subclass type prefix driver status"
+ if criteria_is_relevant "$attrs" && criteria_matches; then
+ show=1
+ fi
fi
# print the info only if the device matches the criteria
@@ -330,15 +409,10 @@ for dev in $($LS -d /proc/device-tree/vdevice/v-scsi* 2> /dev/null) ; do
# device matches
if [[ $criteria != "" ]] ; then
show=0
- check_criteria "name"
- check_criteria "physloc"
- check_criteria "status"
- check_criteria "uniquetype"
- check_criteria "class"
- check_criteria "subclass"
- check_criteria "type"
- check_criteria "prefix"
- check_criteria "driver"
+ attrs="name physloc status uniquetype class subclass type prefix driver"
+ if criteria_is_relevant "$attrs" && criteria_matches; then
+ show=1
+ fi
fi
if [[ $show -ne 0 ]]; then
@@ -395,14 +469,10 @@ for dev in $($LS -d /proc/device-tree/vdevice/v-scsi* 2> /dev/null) ; do
# if there is a criteria in the command line, check if this
# device matches
show=0
- check_criteria "name"
- check_criteria "status"
- check_criteria "physloc"
- check_criteria "parent"
- check_criteria "uniquetype"
- check_criteria "class"
- check_criteria "subclass"
- check_criteria "type"
+ attrs="name status physloc parent uniquetype class subclass type"
+ if criteria_is_relevant "$attrs" && criteria_matches; then
+ show=1
+ fi
else
show=1
fi
@@ -475,15 +545,10 @@ for dev in $($LS -d /proc/device-tree/vdevice/vfc-client* 2> /dev/null) ; do
# device matches
if [[ $criteria != "" ]] ; then
show=0
- check_criteria "name"
- check_criteria "physloc"
- check_criteria "status"
- check_criteria "uniquetype"
- check_criteria "class"
- check_criteria "subclass"
- check_criteria "type"
- check_criteria "prefix"
- check_criteria "driver"
+ attrs="name physloc status uniquetype class subclass type prefix driver"
+ if criteria_is_relevant "$attrs" && criteria_matches; then
+ show=1
+ fi
fi
if [[ $show -ne 0 ]]; then
@@ -543,14 +608,10 @@ for dev in $($LS -d /proc/device-tree/vdevice/vfc-client* 2> /dev/null) ; do
# if there is a criteria in the command line, check if this
# device matches
show=0
- check_criteria "name"
- check_criteria "physloc"
- check_criteria "status"
- check_criteria "parent"
- check_criteria "uniquetype"
- check_criteria "class"
- check_criteria "subclass"
- check_criteria "type"
+ attrs="name physloc status parent uniquetype class subclass type"
+ if criteria_is_relevant "$attrs" && criteria_matches; then
+ show=1
+ fi
else
show=1
fi

View File

@ -1,6 +1,6 @@
Name: powerpc-utils
Version: 1.3.8
Release: 7%{?dist}
Release: 9%{?dist}
Summary: PERL-based scripts for maintaining and servicing PowerPC systems
Group: System Environment/Base
@ -52,6 +52,8 @@ Patch24: 0001-drmgr-fix-remove-by-index-operation.patch
Patch25: powerpc-utils-1.3.8-numa-header.patch
# https://github.com/ibm-power-utilities/powerpc-utils/pull/66
Patch26: powerpc-1.3.8-1b8437319660ed7c69b84ea81032458e615ff3c6.patch
# lsdevinfo: optimize criteria filtering
Patch27: powerpc-utils-1.3.8-4c6dc50d8de1a8b171675ee6b742c9f0250c28a1.patch
%description
PERL-based scripts for maintaining and servicing PowerPC systems.
@ -218,6 +220,12 @@ systemctl daemon-reload >/dev/null 2>&1 || :
%{_mandir}/man8/drmgr.8*
%changelog
* Mon Oct 18 2021 Than Ngo <than@redhat.com> - 1.3.8-9
- Rebuilt
* Mon Oct 11 2021 Than Ngo <than@redhat.com> - 1.3.8-8
- lsdevinfo: optimize criteria filtering
* Fri Jul 16 2021 Than Ngo <than@redhat.com> - 1.3.8-7
- Related: #1938420, Fix checking HCNID array size at boot time