Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package powerpc-utils for openSUSE:Factory checked in at 2021-09-07 21:13:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/powerpc-utils (Old) and /work/SRC/openSUSE:Factory/.powerpc-utils.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "powerpc-utils" Tue Sep 7 21:13:44 2021 rev:118 rq:916775 version:1.3.9 Changes: -------- --- /work/SRC/openSUSE:Factory/powerpc-utils/powerpc-utils.changes 2021-08-25 20:57:34.729210769 +0200 +++ /work/SRC/openSUSE:Factory/.powerpc-utils.new.1899/powerpc-utils.changes 2021-09-07 21:13:53.232756578 +0200 @@ -1,0 +2,6 @@ +Fri Sep 3 18:04:46 UTC 2021 - Michal Suchanek <msucha...@suse.de> + +- Optimize lsdevinfo filtering to prevent LPM timeouts (bsc#1189571 LTC#193419). + + lsdevinfo-optimize-criteria-filtering.patch + +------------------------------------------------------------------- New: ---- lsdevinfo-optimize-criteria-filtering.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ powerpc-utils.spec ++++++ --- /var/tmp/diff_new_pack.SL1GPP/_old 2021-09-07 21:13:53.644757075 +0200 +++ /var/tmp/diff_new_pack.SL1GPP/_new 2021-09-07 21:13:53.644757075 +0200 @@ -28,6 +28,7 @@ Patch1: powerpc-utils-lsprop.patch Patch2: ofpathname_powernv.patch Patch4: libvirt-service-dep.patch +Patch5: lsdevinfo-optimize-criteria-filtering.patch Patch14: fix_kexec_service_name_for_suse.patch BuildRequires: autoconf BuildRequires: automake ++++++ lsdevinfo-optimize-criteria-filtering.patch ++++++ >From 51b50ec77451fb9164d6379bfe3ab9ade8a672c5 Mon Sep 17 00:00:00 2001 From: Scott Cheloha <chel...@linux.ibm.com> Date: Tue, 27 Jul 2021 11:30:58 -0500 Subject: [PATCH] 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 <chel...@linux.ibm.com> --- scripts/lsdevinfo | 197 ++++++++++++++++++++++++++++++---------------- 1 file changed, 129 insertions(+), 68 deletions(-) diff --git a/scripts/lsdevinfo b/scripts/lsdevinfo index 1d9597bc4bc9..7a3cba3bee9f 100755 --- a/scripts/lsdevinfo +++ b/scripts/lsdevinfo @@ -61,37 +61,113 @@ show_version() echo "Written by: Santiago Leon <sl...@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 -- 2.31.1