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 +