Date: Tuesday, July 14, 2015 @ 13:39:54
  Author: alucryd
Revision: 136824

FS#45587: tlp 0.7-3

Added:
  tlp/trunk/fix-udev-event-processing-for-AC-BAT.patch
  tlp/trunk/fix-udev-event-processing-for-USB.patch
Modified:
  tlp/trunk/PKGBUILD

--------------------------------------------+
 PKGBUILD                                   |   14 -
 fix-udev-event-processing-for-AC-BAT.patch |  134 ++++++++++++
 fix-udev-event-processing-for-USB.patch    |  284 +++++++++++++++++++++++++++
 3 files changed, 428 insertions(+), 4 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD    2015-07-14 08:22:33 UTC (rev 136823)
+++ PKGBUILD    2015-07-14 11:39:54 UTC (rev 136824)
@@ -5,18 +5,24 @@
 pkgbase=tlp
 pkgname=('tlp' 'tlp-rdw')
 pkgver=0.7
-pkgrel=2
+pkgrel=3
 arch=('any')
-url='http://linrunner.de/en/tlp/docs/tlp-linux-advanced-power-management.html'
+url='http://linrunner.de/en/tlp/tlp.html'
 license=('GPL2' 'GPL3')
 
source=("$pkgbase-$pkgver.tar.gz::https://github.com/linrunner/TLP/archive/${pkgver}.tar.gz";
-        'tlp-arch.patch')
+        'tlp-arch.patch'
+        'fix-udev-event-processing-for-AC-BAT.patch'
+        'fix-udev-event-processing-for-USB.patch')
 sha256sums=('bd313f478f897a658f2ca7db9665b8ce6796431b952f7df9aa80e59072cea4ea'
-            '833ed3348a46afee9c20119452c98d07caf050d955961beb4fdef76ff4e4a59a')
+            '833ed3348a46afee9c20119452c98d07caf050d955961beb4fdef76ff4e4a59a'
+            '546057c61812d2e788b101c055d87137deb5fcec087e4e3c9a0c3a5ac615b556'
+            '5ed8c2b391c2bc2a06f6d7a615fc24c3e4a6c4060fdee53221ff72eddfc843ae')
 
 prepare() {
   cd TLP-${pkgver}
 
+  patch -Np1 -i ../fix-udev-event-processing-for-AC-BAT.patch
+  patch -Np1 -i ../fix-udev-event-processing-for-USB.patch
   patch -Np1 -i ../tlp-arch.patch
 }
 

Added: fix-udev-event-processing-for-AC-BAT.patch
===================================================================
--- fix-udev-event-processing-for-AC-BAT.patch                          (rev 0)
+++ fix-udev-event-processing-for-AC-BAT.patch  2015-07-14 11:39:54 UTC (rev 
136824)
@@ -0,0 +1,134 @@
+From d8092a1c3ee2183e086312269d0224bf5ffded5e Mon Sep 17 00:00:00 2001
+From: Thomas Koch <linrun...@gmx.net>
+Date: Mon, 13 Jul 2015 22:05:32 +0200
+Subject: [PATCH 1/2] Issues #147, #149: fix udev event processing for AC/BAT
+ switching
+
+Background: systemd-udevd version 221 now kills forked processes
+when the main process (called by RUN=) terminates and stdout/
+stderr have been closed. First occurred on Arch Linux.
+
+Consequences:
+TLP's technique to fork udev event processing in a subshell fails
+and the code applying the settings is aborted prematurely.
+
+In case of tlp-usb-udev removing the subshell is not an option,
+because it would remove the ability to concurrently populate
+the subdevices tree and thus incapacitate the driver blacklisting
+feature.
+
+Solution:
+- Remove subshell forking for AC/BAT switching in tlp
+- Do not close stdout/stdin in tlp-usb-udev subshell to prevent
+  being killed by udev post-processing
+- Reduce wait for subdevices populating in tlp-usb-udev
+---
+ tlp          | 11 +++--------
+ tlp-usb-udev | 62 ++++++++++++++++++++++++++++++++----------------------------
+ 2 files changed, 36 insertions(+), 37 deletions(-)
+
+diff --git a/tlp b/tlp
+index 9f41611..c7c9f12 100755
+--- a/tlp
++++ b/tlp
+@@ -139,14 +139,9 @@ case "$mode" in
+ 
+     auto) # set mode depending on state (called by udev rule)
+         check_root
+-        ( # run in a detached subshell to avoid blocking udev,
+-          # close stdout/stderr
+-            exec 1> /dev/null 2>/dev/null
+-
+-            apply_common_settings $pwrmode
+-            [ "$pwrmode" = "1" ] && poweroff_drivebay 0
+-            set_radio_device_states $pwrmode
+-        ) &
++        apply_common_settings $pwrmode
++        [ "$pwrmode" = "1" ] && poweroff_drivebay 0
++        set_radio_device_states $pwrmode
+         ;;
+ 
+     start) # set mode depending on state (interactive mode)
+diff --git a/tlp-usb-udev b/tlp-usb-udev
+index c31a686..f3b8546 100755
+--- a/tlp-usb-udev
++++ b/tlp-usb-udev
+@@ -71,22 +71,9 @@ usbdev=/sys$1
+ if [ -f $usbdev/power/autosuspend ] || [ -f 
$usbdev/power/autosuspend_delay_ms ]; then
+     # device is autosuspendable
+ 
+-    ( # run remainder in a detached subshell to avoid blocking udev,
+-      # close stdout/stderr
+-        exec 1> /dev/null 2>/dev/null
+-
+-        # initialize driver blacklist from settings
+-        drv_bl=${USB_DRIVER_BLACKLIST:-$DEFAULT_USB_DRIVER_BLACKLIST}
+-
+-        # add wwan driver blacklist if enabled
+-        USB_BLACKLIST_WWAN=${USB_BLACKLIST_WWAN:-1} # default is exclude
+-
+-        if [ $USB_BLACKLIST_WWAN = "1" ]; then
+-            drv_bl="$drv_bl $USB_WWAN_DRIVERS"
+-        fi
+-
+-        # wait for subdevices to populate via parallel udev events (not 
handled here)
+-        sleep 2.0
++    (   # run remainder in a detached subshell to allow udev to populate
++        # subdevices in parallel; do *not* close stdin/stdout to avoid
++        # being "sanitized" (killed) by udev post-processing
+ 
+         # apply autosuspend
+         ctrlf="control"
+@@ -105,19 +92,36 @@ if [ -f $usbdev/power/autosuspend ] || [ -f 
$usbdev/power/autosuspend_delay_ms ]
+             control="on"
+             exc="_dev_black"
+         else
+-            # check subdevices for blacklisted drivers
+-            for subdev in $usbdev/*:*; do
+-                # get driver name from subdev uevent file
+-                drv=$(sed -rn 's/^DRIVER=(.*)/\1/p' $subdev/uevent)
+-
+-                # check against driver blacklist
+-                if wordinlist "$drv" "$drv_bl"; then
+-                    # driver is blacklisted
+-                    control="on"
+-                    exc="_drv_black"
+-                    break
+-                fi
+-            done
++            # initialize driver blacklist from settings
++            drv_bl=${USB_DRIVER_BLACKLIST:-$DEFAULT_USB_DRIVER_BLACKLIST}
++
++            # add wwan driver blacklist if enabled
++            USB_BLACKLIST_WWAN=${USB_BLACKLIST_WWAN:-1} # default is exclude
++            if [ $USB_BLACKLIST_WWAN = "1" ]; then
++                drv_bl="$drv_bl $USB_WWAN_DRIVERS"
++            fi
++
++            if [ -n "$drv_bl" ]; then
++                # proceed only when driver blacklist is not empty
++
++                # wait for subdevices to populate via parallel udev events
++                # (not handled here)
++                sleep 0.5
++
++                # check subdevices for blacklisted drivers
++                for subdev in $usbdev/*:*; do
++                    # get driver name from subdev uevent file
++                    drv=$(sed -rn 's/^DRIVER=(.*)/\1/p' $subdev/uevent)
++
++                    # check against driver blacklist
++                    if wordinlist "$drv" "$drv_bl"; then
++                        # driver is blacklisted
++                        control="on"
++                        exc="_drv_black"
++                        break
++                    fi
++                done
++            fi
+         fi
+ 
+         if [ -f $usbdev/power/control ]; then
+-- 
+1.9.1
+

Added: fix-udev-event-processing-for-USB.patch
===================================================================
--- fix-udev-event-processing-for-USB.patch                             (rev 0)
+++ fix-udev-event-processing-for-USB.patch     2015-07-14 11:39:54 UTC (rev 
136824)
@@ -0,0 +1,284 @@
+From 9694c03ee7522b8fc4a73aec20e51159b4ea0fdb Mon Sep 17 00:00:00 2001
+From: Thomas Koch <linrun...@gmx.net>
+Date: Mon, 13 Jul 2015 21:46:00 +0200
+Subject: [PATCH 2/2] Issues #147, 149: fix udev event processing for USB
+ hotplugging
+
+Rationale: USB_DRIVER_BLACKLIST code detecting drivers by iterating
+subdevices is broken since systemd-udevd v221 (and higher).
+
+Solution: revert implementation to version 0.6 code
+- Remove detached subshell
+- Detect usbhid via subdevices' bInterfaceClass = 03
+- Detect wwan devices via idVendor static blacklist
+- Remove USB_DRIVER_BLACKLIST feature
+---
+ default       |   5 ---
+ tlp-functions |  36 ++++++++--------
+ tlp-stat      |   3 +-
+ tlp-usb-udev  | 132 +++++++++++++++++++++++++++++-----------------------------
+ 4 files changed, 83 insertions(+), 93 deletions(-)
+
+diff --git a/default b/default
+index fe0d134..b19ce4a 100644
+--- a/default
++++ b/default
+@@ -172,11 +172,6 @@ USB_AUTOSUSPEND=1
+ # Note: input devices (usbhid) are excluded automatically (see below)
+ #USB_BLACKLIST="1111:2222 3333:4444"
+ 
+-# Exclude devices assigned to the listed drivers from USB autosuspend.
+-# Default is "usbhid" (input devices); use "" to disable the feature
+-# completely. Separate multiple drivers with spaces.
+-USB_DRIVER_BLACKLIST="usbhid"
+-
+ # WWAN devices are excluded from USB autosuspend:
+ # 0=do not exclude / 1=exclude
+ USB_BLACKLIST_WWAN=1
+diff --git a/tlp-functions b/tlp-functions
+index 8a1a9c4..e52ed51 100755
+--- a/tlp-functions
++++ b/tlp-functions
+@@ -53,7 +53,7 @@ readonly CPU_TURBO_PSTATE=$INTEL_PSTATED/no_turbo
+ readonly USBD=/sys/bus/usb/devices
+ readonly USB_TIMEOUT=2
+ readonly USB_TIMEOUT_MS=2000
+-readonly USB_WWAN_DRIVERS="cdc_acm cdc_wdm cdc_ether hso qcserial sierra"
++readonly USB_WWAN_VENDORS="0bdb 05c6 1199"
+ readonly USB_DONE=usb_done
+ 
+ readonly DOCKGLOB="/sys/devices/platform/dock.?"
+@@ -1487,16 +1487,6 @@ set_usb_suspend () { # activate usb autosuspend for all 
devices except input and
+     if [ "$USB_AUTOSUSPEND" = "1" ]; then
+         # autosuspend is configured
+ 
+-        # initialize driver blacklist from settings
+-        drv_bl=${USB_DRIVER_BLACKLIST:-$DEFAULT_USB_DRIVER_BLACKLIST}
+-
+-        # add wwan driver blacklist if enabled
+-        USB_BLACKLIST_WWAN=${USB_BLACKLIST_WWAN:-1} # default is exclude
+-
+-        if [ $USB_BLACKLIST_WWAN = "1" ]; then
+-            drv_bl="$drv_bl $USB_WWAN_DRIVERS"
+-        fi
+-
+         # iterate devices
+         devices=$(ls $USBD 2> /dev/null | grep -v ':')
+ 
+@@ -1518,19 +1508,27 @@ set_usb_suspend () { # activate usb autosuspend for 
all devices except input and
+                         control="on"
+                         exc="_dev_black"
+                     else
+-                        # check subdevices for blacklisted drivers
++                        # check for hid subdevices
+                         for subdev in $USBD/$usbdev/*:*; do
+-                            # get driver name from subdev uevent file
+-                            drv=$(sed -rn 's/^DRIVER=(.*)/\1/p' 
$subdev/uevent)
+-
+-                            # check against driver blacklist
+-                            if wordinlist "$drv" "$drv_bl"; then
+-                                # driver is blacklisted
++                            if [ -d $subdev ] && [ "$(cat 
$subdev/bInterfaceClass)" = "03" ]; then
+                                 control="on"
+-                                exc="_drv_black"
++                                exc="_hid_black"
+                                 break
+                             fi
+                         done
++
++                        if [ -z "$exc" ]; then
++                            # check for wwan vendor ids
++                            USB_BLACKLIST_WWAN=${USB_BLACKLIST_WWAN:-1} # 
default is exclude
++
++                            if [ $USB_BLACKLIST_WWAN = "1" ]; then
++                                vendor="$(cat $USBD/$usbdev/idVendor)"
++                                if wordinlist "$vendor" "$USB_WWAN_VENDORS"; 
then
++                                    control="on"
++                                    exc="_wwan_black"
++                                fi
++                            fi
++                        fi
+                     fi
+                 fi
+ 
+diff --git a/tlp-stat b/tlp-stat
+index 5a179f3..f958df2 100755
+--- a/tlp-stat
++++ b/tlp-stat
+@@ -872,9 +872,8 @@ if [ "$show_usb" = "1" ] || [ "$show_all" = "1" ]; then
+     fi
+     echo "device whitelist   = ${USB_WHITELIST:=(not configured)}"
+     echo "device blacklist   = ${USB_BLACKLIST:=(not configured)}"
+-    echo "driver blacklist   = ${USB_DRIVER_BLACKLIST:=(not configured)}"
+     if [ "$USB_BLACKLIST_WWAN" = "1" ]; then
+-        echo "wwan blacklist     = enabled ($USB_WWAN_DRIVERS)"
++        echo "wwan blacklist     = enabled"
+     else
+         echo "wwan blacklist     = disabled"
+     fi
+diff --git a/tlp-usb-udev b/tlp-usb-udev
+index f3b8546..917fc5c 100755
+--- a/tlp-usb-udev
++++ b/tlp-usb-udev
+@@ -13,8 +13,7 @@ readonly LOGGER=logger
+ readonly USBD=/sys/bus/usb/devices
+ readonly USB_TIMEOUT=2
+ readonly USB_TIMEOUT_MS=2000
+-readonly USB_WWAN_DRIVERS="cdc_acm cdc_wdm cdc_ether hso qcserial sierra"
+-readonly DEFAULT_USB_DRIVER_BLACKLIST="usbhid"
++readonly USB_WWAN_VENDORS="0bdb 05c6 1199"
+ 
+ readonly RUNDIR=/var/run/tlp
+ readonly USB_DONE=usb_done
+@@ -71,84 +70,83 @@ usbdev=/sys$1
+ if [ -f $usbdev/power/autosuspend ] || [ -f 
$usbdev/power/autosuspend_delay_ms ]; then
+     # device is autosuspendable
+ 
+-    (   # run remainder in a detached subshell to allow udev to populate
+-        # subdevices in parallel; do *not* close stdin/stdout to avoid
+-        # being "sanitized" (killed) by udev post-processing
+-
+-        # apply autosuspend
+-        ctrlf="control"
+-        autof="autosuspend_delay_ms"
+-        usbid="$(cat $usbdev/idVendor):$(cat $usbdev/idProduct)"
+-        busdev="Bus $(cat $usbdev/busnum) Dev $(cat $usbdev/devnum)"
++    # apply autosuspend
++    ctrlf="control"
++    autof="autosuspend_delay_ms"
++    usbid="$(cat $usbdev/idVendor):$(cat $usbdev/idProduct)"
++    busdev="Bus $(cat $usbdev/busnum) Dev $(cat $usbdev/devnum)"
++    control="auto"
++    exc=""
++    chg=0
++
++    if wordinlist "$usbid" "$USB_WHITELIST"; then
++        # device is in whitelist -- whitelist always wins
+         control="auto"
+-        exc=""
+-
+-        if wordinlist "$usbid" "$USB_WHITELIST"; then
+-            # device is in whitelist -- whitelist always wins
+-            control="auto"
+-            exc="_dev_white"
+-        elif wordinlist "$usbid" "$USB_BLACKLIST"; then
+-            # device is in blacklist
+-            control="on"
+-            exc="_dev_black"
+-        else
+-            # initialize driver blacklist from settings
+-            drv_bl=${USB_DRIVER_BLACKLIST:-$DEFAULT_USB_DRIVER_BLACKLIST}
++        exc="_dev_white"
++    elif wordinlist "$usbid" "$USB_BLACKLIST"; then
++        # device is in blacklist
++        control="on"
++        exc="_dev_black"
++    else
++        # wait for subdevices to populate
++        sleep 0.5
++
++        # check for hid subdevices
++        for subdev in $usbdev/*:*; do
++            if [ -d $subdev ] && [ "$(cat $subdev/bInterfaceClass)" = "03" ]; 
then
++                control="on"
++                exc="_hid_black"
++                break
++            fi
++        done
+ 
+-            # add wwan driver blacklist if enabled
++        if [ -z "$exc" ]; then
++            # check for wwan vendor ids
+             USB_BLACKLIST_WWAN=${USB_BLACKLIST_WWAN:-1} # default is exclude
+-            if [ $USB_BLACKLIST_WWAN = "1" ]; then
+-                drv_bl="$drv_bl $USB_WWAN_DRIVERS"
+-            fi
+ 
+-            if [ -n "$drv_bl" ]; then
+-                # proceed only when driver blacklist is not empty
+-
+-                # wait for subdevices to populate via parallel udev events
+-                # (not handled here)
+-                sleep 0.5
+-
+-                # check subdevices for blacklisted drivers
+-                for subdev in $usbdev/*:*; do
+-                    # get driver name from subdev uevent file
+-                    drv=$(sed -rn 's/^DRIVER=(.*)/\1/p' $subdev/uevent)
+-
+-                    # check against driver blacklist
+-                    if wordinlist "$drv" "$drv_bl"; then
+-                        # driver is blacklisted
+-                        control="on"
+-                        exc="_drv_black"
+-                        break
+-                    fi
+-                done
++            if [ $USB_BLACKLIST_WWAN = "1" ]; then
++                vendor="$(cat $usbdev/idVendor)"
++                if wordinlist "$vendor" "$USB_WWAN_VENDORS"; then
++                    control="on"
++                    exc="_wwan_black"
++                fi
+             fi
+         fi
++    fi
+ 
+-        if [ -f $usbdev/power/control ]; then
++    if [ -f $usbdev/power/control ]; then
++        if [ "$(cat $usbdev/power/control)" != "$control" ]; then
++            # Write actual changes only
+             echo "$control" > $usbdev/power/control
+-        else
+-            # level is deprecated
++            chg=1
++        fi
++    else
++        # level is deprecated
++        if [ "$(cat $usbdev/power/level)" != "$control" ]; then
++            # Write actual changes only
+             echo "$control" > $usbdev/power/level
+-            ctrlf="level"
++            chg=1
+         fi
++        ctrlf="level"
++    fi
+ 
+-        if [ "$X_TLP_USB_SET_AUTOSUSPEND_DELAY" = "1" ]; then
+-            # set autosuspend_delay
+-            if [ -f $usbdev/power/autosuspend_delay_ms ]; then
+-                echo $USB_TIMEOUT_MS > $usbdev/power/autosuspend_delay_ms
+-            else
+-                # autosuspend is deprecated
+-                echo $USB_TIMEOUT > $usbdev/power/autosuspend
+-                autof="autosuspend"
+-            fi
+-            echo_debug "usb" "udev_usb.$control$exc: $busdev ID $usbid 
$usbdev [$ctrlf $autof]"
++    if [ "$X_TLP_USB_SET_AUTOSUSPEND_DELAY" = "1" ]; then
++        # set autosuspend_delay
++        if [ -f $usbdev/power/autosuspend_delay_ms ]; then
++            echo $USB_TIMEOUT_MS > $usbdev/power/autosuspend_delay_ms
+         else
+-            # default: do not change autosuspend_delay, i.e. keep kernel 
default setting
+-            echo_debug "usb" "udev_usb.$control$exc: $busdev ID $usbid 
$usbdev [$ctrlf]"
++            # autosuspend is deprecated
++            echo $USB_TIMEOUT > $usbdev/power/autosuspend
++            autof="autosuspend"
+         fi
+-
+-        exit 0
+-    ) &
++        echo_debug "usb" "udev_usb.$control$exc: $busdev ID $usbid $usbdev 
[$ctrlf $autof]"
++    elif [ $chg -eq 1 ]; then
++        # default: change control but not autosuspend_delay, i.e. keep kernel 
default setting
++        echo_debug "usb" "udev_usb.$control$exc: $busdev ID $usbid $usbdev 
[$ctrlf]"
++    else
++        # we didn't change anything actually
++        echo_debug "usb" "udev_usb.$control$exc: $busdev ID $usbid $usbdev"
++    fi
+ fi
+ 
+ exit 0
+-- 
+1.9.1
+

Reply via email to