rickysarraf / laptop-mode-tools

Power Savings tool for Linux
https://www.researchut.com/tags/laptop-mode-tools/
GNU General Public License v2.0
557 stars 46 forks source link

Wrong state @ laptops with two batteries #68

Closed utrack closed 8 years ago

utrack commented 8 years ago

Hello! I'm stuck with a bug on Lenovo T450. T450 has two batteries (internal and external/swappable/usual one). LMT always thinks the laptop is plugged in if external battery presents; if I disconnect it the daemon works as intended.

I'm using Arch Linux with laptop-mode-tools-git AUR package.

Where to look further?

rickysarraf commented 8 years ago

https://github.com/rickysarraf/laptop-mode-tools/blob/lmt-upstream/usr/sbin/laptop_mode#L742

The code is supposed to take care of multiple batteries. In the past, users have reported similar bugs and we've fixed them. But I personally have never tested such setup due to lack of hardware.

rickysarraf commented 8 years ago

The best option for you is to run Laptop Mode Tools in verbose mode.

VERBOSE_OUPUT=1 in /etc/laptop-mode/laptop-mode.conf and then share relevant details.

utrack commented 8 years ago

Didn't find anything really verbose; launched full-on debug. AC: http://pastebin.com/rJhpHKs1 Two batteries: http://pastebin.com/hgi98C27

utrack commented 8 years ago

Relevant stuff: With two batteries, no AC:

λ ~
» cat /sys/class/power_supply/BAT0/status                                                                                                                                                                                                                                                                                                                2016-08-15 15:46:59
Unknown

λ ~
» cat /sys/class/power_supply/AC/online                                                                                                                                                                                                                                                                                                                  2016-08-15 15:47:02
0

λ ~
» cat /sys/class/power_supply/BAT1/status                                                                                                                                                                                                                                                                                                                2016-08-15 15:47:08
Discharging

With one battery:

λ ~
» cat /sys/class/power_supply/BAT1/status                                                                                                                                                                                                                                                                                                                2016-08-15 15:47:11
cat: /sys/class/power_supply/BAT1/status: No such file or directory

λ ~
» cat /sys/class/power_supply/BAT0/status                                                                                                                                                                                                                                                                                                                2016-08-15 15:47:32
Discharging

λ ~
» cat /sys/class/power_supply/AC/online                                                                                                                                                                                                                                                                                                                  2016-08-15 15:47:34
0
rickysarraf commented 8 years ago

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512

I'll look at the complete logs later, but from this email, for what you've shared, it looks good.

On Mon, 2016-08-15 at 05:48 -0700, Nick K wrote:

Relevant stuff: With two batteries, no AC: λ ~ » cat /sys/class/power_supply/BAT0/status                                                                                                                                                                                                                                                                                                                    2016-08-15 15:46:59 Unknown

LMT is particular in how it determines power status, by specifically looking for string "Discharging".

Note to self: So even it the bat status lists as "Unknown", it is not a problem because the next item in the loop will get the proper battery's state.

λ ~ » cat /sys/class/power_supply/AC/online                                                                                                                                                                                                                                                                                                                      2016-08-15 15:47:02 0

λ ~ » cat /sys/class/power_supply/BAT1/status                                                                                                                                                                                                                                                                                                                    2016-08-15 15:47:08 Discharging

This one, as mentioned above.

With one battery: λ ~ » cat /sys/class/power_supply/BAT1/status                                                                                                                                                                                                                                                                                                                    2016-08-15 15:47:11 cat: /sys/class/power_supply/BAT1/status: No such file or directory

λ ~ » cat /sys/class/power_supply/BAT0/status                                                                                                                                                                                                                                                                                                                    2016-08-15 15:47:32 Discharging

And in case of 1 battery too, it is fine, because of this.

λ ~ » cat /sys/class/power_supply/AC/online                                                                                                                                                                                                                                                                                                                      2016-08-15 15:47:34 0


Ritesh Raj Sarraf RESEARCHUT - http://www.researchut.com "Necessity is the mother of invention." -----BEGIN PGP SIGNATURE-----

iQIcBAEBCgAGBQJXseXcAAoJEKY6WKPy4XVpMGUQAJyGvWdFXnDm/vpnQ0mHIPjv lrj7v3B46hj1B7D6FkmBWmaWDjYU1Y4rDF6EEGj05oWvUZJ22IHbqp+ccYfjwRTw 2E/Z6fwVEMY/PFS1mSmY9uH3dmE6JUb90VSDHsEsUermzO+pNOuyfnJuS+Q3GiNo t4pg68zIxU3sYOmzNCpgglrmF86eSNzeATw0JNLB0VwbCJKKDbEKiQzxWFQZIIUM jM4A8Xt584gtfbW9e5A/9vqj2UmyENMlUbFMgvh5CGwt/P/Rqjq6DbtIBeX0tLCZ hnxsL+TJJQXvwWQrBe97+HrFVyYhwVD3vcnp7brVmmsYClK5+C1Npvg0YYGlaOOa 0AnneQ8Z1sK4b9v7PBePwm1vXDZlG515caMdGMnJRbq7E+vuPazO/tBxtoeOpmzy LFiobxLTN5myJ49kv0/wo5jhClnTLM4RONWVLnfxnJjZqz0CzE84d25CNHb3y+pL d3+CKC1DDt+dYMws08jevZOF98CpV/mD4aJbqw0wJ+2iRN/J+dSwnpBPiCvYz9Z5 QULpV1/JcHVzvP72Bz1Z5rpQHxQDLGAjjgjJlw0KoWOzrhc7fhaPeV867O34yA/X jvAw51QLkqxs/bj5wGU4xuZTuXhBP+v4+cKDzhqVix2MMW+kP9Gvn0WA+y3cr1XB D1XHqsnmHVo/zkKn7Lk7 =EBdg -----END PGP SIGNATURE-----

rickysarraf commented 8 years ago

Please have bug logs attached here. It'll help other users in the future.

lmt-2bat-bug.txt

rickysarraf commented 8 years ago

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512

On Mon, 2016-08-15 at 21:25 +0530, Ritesh Raj Sarraf wrote:

On Mon, 2016-08-15 at 05:48 -0700, Nick K wrote:

Relevant stuff: With two batteries, no AC: λ ~ » cat

/sys/class/power_supply/BAT0/status                                           

                                                                              

                                                                              

                                                                                                          2016-08-15 15:46:59 Unknown  

LMT is particular in how it determines power status, by specifically looking for string "Discharging".

Note to self: So even it the bat status lists as "Unknown", it is not a problem because the next item in the loop will get the proper battery's state.

As mentioned, the same is well done in LMT. From the logs shared by the user, it is clear. Snippet below.

+ for POWER_SUPPLY in '/sys/class/power_supply/*'
+ '[' -f /sys/class/power_supply/AC/type ']'
cat $POWER_SUPPLY/type
++ cat /sys/class/power_supply/AC/type
+ '[' Mains == Mains ']'
+ log VERBOSE 'Determining power state from /sys/class/power_supply/AC/online.'
+ '[' x1 = x1 ']'
+ '[' -x /usr/bin/logger -a VERBOSE '!=' STATUS ']'
+ '[' VERBOSE = MSG ']'
+ '[' VERBOSE = ERR ']'
+ '[' VERBOSE = VERBOSE ']'
+ '[' x1 = x1 ']'
+ logger -p daemon.debug -t laptop-mode 'Determining power state from
/sys/class/power_supply/AC/online.'
+ '[' VERBOSE = VERBOSE ']'
+ '[' 1 = 1 ']'
+ echo 'Determining power state from /sys/class/power_supply/AC/online.'
Determining power state from /sys/class/power_supply/AC/online.
+ FOUND_SYS_CLASS_POWER_SUPPLY_AC=1
cat $POWER_SUPPLY/online
++ cat /sys/class/power_supply/AC/online
+ '[' 0 = 1 ']'
+ for POWER_SUPPLY in '/sys/class/power_supply/*'
+ '[' -f /sys/class/power_supply/BAT0/type ']'
cat $POWER_SUPPLY/type
++ cat /sys/class/power_supply/BAT0/type
+ '[' Battery == Mains ']'
cat $POWER_SUPPLY/type
++ cat /sys/class/power_supply/BAT0/type
+ '[' Battery == Battery ']'
+ log VERBOSE 'Determining power state from status of battery
/sys/class/power_supply/BAT0.'
+ '[' x1 = x1 ']'
+ '[' -x /usr/bin/logger -a VERBOSE '!=' STATUS ']'
+ '[' VERBOSE = MSG ']'
+ '[' VERBOSE = ERR ']'
+ '[' VERBOSE = VERBOSE ']'
+ '[' x1 = x1 ']'
+ logger -p daemon.debug -t laptop-mode 'Determining power state from status of
battery /sys/class/power_supply/BAT0.'
+ '[' VERBOSE = VERBOSE ']'
+ '[' 1 = 1 ']'
+ echo 'Determining power state from status of battery
/sys/class/power_supply/BAT0.'
Determining power state from status of battery /sys/class/power_supply/BAT0.
+ FOUND_SYS_CLASS_POWER_SUPPLY_AC=1
cat $POWER_SUPPLY/status
++ cat /sys/class/power_supply/BAT0/status
+ '[' Unknown '!=' Discharging ']'
+ ON_AC=1
+ for POWER_SUPPLY in '/sys/class/power_supply/*'
+ '[' -f /sys/class/power_supply/BAT1/type ']'
cat $POWER_SUPPLY/type
++ cat /sys/class/power_supply/BAT1/type
+ '[' Battery == Mains ']'
cat $POWER_SUPPLY/type
++ cat /sys/class/power_supply/BAT1/type
+ '[' Battery == Battery ']'
+ log VERBOSE 'Determining power state from status of battery
/sys/class/power_supply/BAT1.'
+ '[' x1 = x1 ']'
+ '[' -x /usr/bin/logger -a VERBOSE '!=' STATUS ']'
+ '[' VERBOSE = MSG ']'
+ '[' VERBOSE = ERR ']'
+ '[' VERBOSE = VERBOSE ']'
+ '[' x1 = x1 ']'
+ logger -p daemon.debug -t laptop-mode 'Determining power state from status of
battery /sys/class/power_supply/BAT1.'
+ '[' VERBOSE = VERBOSE ']'
+ '[' 1 = 1 ']'
+ echo 'Determining power state from status of battery
/sys/class/power_supply/BAT1.'
Determining power state from status of battery /sys/class/power_supply/BAT1.
+ FOUND_SYS_CLASS_POWER_SUPPLY_AC=1
cat $POWER_SUPPLY/status
++ cat /sys/class/power_supply/BAT1/status
+ '[' Discharging '!=' Discharging ']'
+ '[' 1 = 1 ']'
+ log VERBOSE 'Not trying other options, already found a power supply.'
+ '[' x1 = x1 ']'
+ '[' -x /usr/bin/logger -a VERBOSE '!=' STATUS ']'
+ '[' VERBOSE = MSG ']'
+ '[' VERBOSE = ERR ']'
+ '[' VERBOSE = VERBOSE ']'
+ '[' x1 = x1 ']'
+ logger -p daemon.debug -t laptop-mode 'Not trying other options, already found
a power supply.'
+ '[' VERBOSE = VERBOSE ']'
+ '[' 1 = 1 ']'
+ echo 'Not trying other options, already found a power supply.'
Not trying other options, already found a power supply.
+ INIT=0
+ FORCE=0
+ INITSCRIPT_STOP=0
+ '[' '' = status ']'
+ '[' '' '!=' readconfig -a '' '!=' defaults ']'

@utrack I see nothing wrong so far. What exactly is the problem you face ? Does LMT not come into affect when 2 batteries are used ? Because from the logs it is clear that it could detect the state from the second battery, and proceed accordingly.


Ritesh Raj Sarraf RESEARCHUT - http://www.researchut.com "Necessity is the mother of invention." -----BEGIN PGP SIGNATURE-----

iQIcBAEBCgAGBQJXsefsAAoJEKY6WKPy4XVp48AQALefvs6ilw92BL/VN6tdxAq0 BK081l/ql33DajTaC7pDQ4HJDeJsmTCuaW3ehRspimrVNLexDf3ucee8x/j/OfAe D2bKLJqVJuniBBToR3aEOZZGuXNAqvAdkdS/ymfVLzeuGtHtn75pVuuy4le7O+MR 1TduOPRlSu9+LIkfcMqIsvj3tHfom1aUQi2wy5VX+pRo2OCxN7arut7BzlsJ+fg4 zUM+FuV6eCzvQOnENr8IsaIv80h/88UiTuOc/0xdORxSBDqkMUtu+k/8qGeRaw1e /BeLGQsDDrdB/gAlWhw5RlHMp1QeblNUUoCrrhxdn94oaApr7DEV7Ife5hCtOaxy uXeUX5FQ0TZIvm06sTe+1zDaf3/WfYEKG+LbsSKLtFkLuZpdPLkDc6Awr38kyL4J YVcuuc5wYkh4U5AzyiZ92OwOAGtjYVQf2caA/VxNX5vJ88ZXXqZ27kmh7J7Pjkf5 kdrMbpKdbbb9cUuOxXArPBeJvWe/oT/HyGZhyDk2dBH7LQwnVPk4hxApldnV0mxJ sCChc/5TdV/6tPH4MOGs3JoEkl5NxP2MyuB51raX3LVWeJI/60WNZzTwDg8CKz/d CuhTnhNldgT5E/LjKm2WoSkoahqIgQbhCSp4DbKxbKTepBEoRfFMsEdHjhR+rwF6 bbkHXHkP3qOS6bzAxiFl =qxGc -----END PGP SIGNATURE-----

rickysarraf commented 8 years ago

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512

On Mon, 2016-08-15 at 05:46 -0700, Nick K wrote:

Didn't find anything really verbose; launched full-on debug. AC: http://pastebin.com/rJhpHKs1 Two batteries: http://pastebin.com/hgi98C27

  • logger -p daemon.debug -t laptop-mode 'Checking if desired state is different from current state.'
  • '[' VERBOSE = VERBOSE ']'
  • '[' 1 = 1 ']'
  • echo 'Checking if desired state is different from current state.' Checking if desired state is different from current state.
  • '[' -f /var/run/laptop-mode-tools/state ']'
  • read WAS_ACTIVE WAS_ON_AC WAS_ACTIVATE_WITH_POSSIBLE_DATA_LOSS WAS_STATE
  • '[' enabled '!=' '' ']'
  • '[' 0 -eq 0 -a 1 -eq 1 -a 0 -eq 0 -a enabled = enabled -a 0 -eq 0 ']'
  • '[' 0 -eq 1 ']'
  • log STATUS 'enabled, not active [unchanged]'
  • '[' x1 = x1 ']'
  • '[' -x /usr/bin/logger -a STATUS '!=' STATUS ']'
  • '[' STATUS = VERBOSE ']'
  • '[' STATUS = ERR ']'
  • echo 'enabled, not active [unchanged]' enabled, not active [unchanged]
  • exit 0

Your logs show "enabled, not active", which should only happen if no state was sensed. What happens if you, at this stage, plug in your ac adapter and then unplug it ?

PS: Your logs above clearly showed that they were able to detect the "Discharging" status from BAT1 (2nd battery).

Can you share your output of systemctl status laptop-mode ? What is the content in /var/run/laptop-mode-tools/state ?


Ritesh Raj Sarraf RESEARCHUT - http://www.researchut.com "Necessity is the mother of invention." -----BEGIN PGP SIGNATURE-----

iQIcBAEBCgAGBQJXsesqAAoJEKY6WKPy4XVp9nUP/14gUH36HC2w3CGN/x7lOFz5 RV/oKcSg68nbn76/5PLSraRy8SGVnpuVNvPSu1FMwr1jao5S8uaVcu6BdcHtSTO9 NINXGRhjqKSrJNjdDvgRajnPsDjQhpmsEW/glkuuQ6hHAIkm3rFfxz9H6u5n+q8t YMLf4cRHaiOVOeuxmwkA4dX332zf902jVrZIBxAxJbz5W333XlVrRmuFHKEO6qCE lBb9t52Q7tNgwDKuNaqTz7KFkRpuNA+pxC79ZmC3a/cN+e795e34EaSnX7uxuUPl AbErTNGs4hVuwoFA7a+Vz0F8PEo00d6yZITa+s58sZRAfmvqrWeldwWtERlk34s0 vzpYITiGmf4buAfe2Q+ynxYQNuzI1h++wlXgNp379IHXkryj2W/Brsz1O6HdVM6H ESgHqINSCt9NMEv44ZwIbBalikrj1S2AIGxOXhPbARwu1dc5/wCHtpgJ0/UDfRp5 PZJs6XUaTy4C6ZF+JPNmMf43dm0tZ2A1I3XuJEnl3Jfd+3ukXQ01g8XUHfIxYZbX 9mrzdjI2XC9EMeMBjE9amR0B4agpilhAgonW0oX/6ExCj4xPjEqiAQ6kG66JWkP9 kkNIhsDN56HfuKKj0Tng72i0iejNiaabMtFj1/9Xy8Z+ZUQ4J3hbOxzwtvleSGWD /1IM6EN7ELm3FA70F4lu =zzrE -----END PGP SIGNATURE-----

rickysarraf commented 8 years ago

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512

On Mon, 2016-08-15 at 21:47 +0530, Ritesh Raj Sarraf wrote:

Your logs show "enabled, not active", which should only happen if no state was sensed. What happens if you, at this stage, plug in your ac adapter and then unplug it ?

PS: Your logs above clearly showed that they were able to detect the "Discharging" status from BAT1 (2nd battery).

So, here's the bug.

The problem is when BAT1 is present, BAT0 is reported as "Unknown". Which is wrong by the kernel power supply subsystem, to report it as "Unknown". :-(

How should we fix this????


Ritesh Raj Sarraf RESEARCHUT - http://www.researchut.com "Necessity is the mother of invention." -----BEGIN PGP SIGNATURE-----

iQIcBAEBCgAGBQJXseyxAAoJEKY6WKPy4XVpoBcP/2d/+zRsJuJ31dxLEnMpW9vC u0diWuxIQwLyHvG3j0X7zskwtQ55rnXupiN4SlbMXQ0fNB5UKS7OJ9745XTcWFE9 Ah8OM8iKetmFUzF5rwl3jOjO3/1nZczplh9XC7omqKWeOjjT1+V3r2hESWLM+Kfc Bt+YshSGoid8am4WbSn9eIo7FADvNhp8fE2qhh0+bngtAGZyGPaRmkvljOKWxcCu WKlgnWcb65PmLDrqMg8YBAEtL34Z+S3ibMkZH6we2rMSUGOFgnsqPFUogqiVsvni oYtptLXiHWs0CrxZOzbbSw4xSoo+zP/IJr21OhU8L9Nyohmpe3/JfHqN/RZ45Ehi mGQiW+t3tNEqC9gIoXtv6J1zCfffRX8078ZMfhvAzIg787i+Zmbh/DSbJyQcH1xx WH9xqIN4A6fpjhYrGCeBUiQZ2gy99wPtL967Iu77QLNKMO0esK171fvOh27DFlK+ eWnI4oDoqknQT30/Mr3oNIQYMoLNsIPKf9ceyIy/eBE74bAxAKf3runPXeFOi7ZS MPY70jQNwMA+AnNtBlCtdu/lme2w+WXHnYs3tOaREab2wgSI5NVFaaoj7bkFwy+S 36e32ZSnKmiwiaCPMPJ1RmVdbd/bzLC/5avJy2lhdy6Zk1oQc/LDByfQUViFBiB7 GIiDcrf7eepDfln69ZZG =03Qo -----END PGP SIGNATURE-----

rickysarraf commented 8 years ago

It seems you may be having a kernel bug @utrack, and I'm no expert on ACPI or the Linux kernel. I'd urge you to post this finding on the linux-acpi development list.

The problem seems to be that, when using 2 batteries, one of the battery (primary?) inherits property "Unknown" for its state, which is wrong. This I say assuming that both your battery are good. But irrespective, even if it was a broken battery, it should have been reported mostly as discharging.

This reminds me of an acpi bug on one of my machines too. The git log has the details about its buggy behavior. https://github.com/rickysarraf/laptop-mode-tools/commit/09b98315a9c752dee0cfbd1ee66a9a91fe10bb1f

And I really don't have a fix for this in LMT. But for you specifically, you could try the following change, but I'd suggest you report this as a bug with your distro and the upstream folks.

rrs@learner:~/.rrs-home/devel/Laptop-Mode-Tools/laptop-mode-tools (lmt-upstream)$ git diff
diff --git a/usr/sbin/laptop_mode b/usr/sbin/laptop_mode
index 23abbdf..b7966ce 100755
--- a/usr/sbin/laptop_mode
+++ b/usr/sbin/laptop_mode
@@ -466,7 +466,9 @@ lmt_load_config ()
                                FOUND_SYS_CLASS_POWER_SUPPLY_AC=1
                                 #INFO: Because there are and will always be br0ken batteries
                                if [ "$(cat $POWER_SUPPLY/status)" != "Discharging" ]; then
-                                       ON_AC=1
+                                       if [ "$(cat $POWER_SUPPLY/status)" != "Unknown" ]; then
+                                               ON_AC=1
+                                        fi
                                fi
                        fi
                fi
2016-08-15 / 22:54:10 ♒♒♒  ☺  
static int acpi_battery_get_property(struct power_supply *psy,
                                     enum power_supply_property psp,
                                     union power_supply_propval *val)
{
        int ret = 0;
        struct acpi_battery *battery = to_acpi_battery(psy);

        if (acpi_battery_present(battery)) {
                /* run battery update only if it is present */
                acpi_battery_get_state(battery);
        } else if (psp != POWER_SUPPLY_PROP_PRESENT)
                return -ENODEV;
        switch (psp) {
        case POWER_SUPPLY_PROP_STATUS:
                if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
                        val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
                else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
                else if (acpi_battery_is_charged(battery))
                        val->intval = POWER_SUPPLY_STATUS_FULL;
                else
                        val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
                break;
        case POWER_SUPPLY_PROP_PRESENT:
                val->intval = acpi_battery_present(battery);
                break;
        case POWER_SUPPLY_PROP_TECHNOLOGY:
                val->intval = acpi_battery_technology(battery);
                break;
        case POWER_SUPPLY_PROP_CYCLE_COUNT:
                val->intval = battery->cycle_count;
                break;
        case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
                if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
                        ret = -ENODEV;
                else
                        val->intval = battery->design_voltage * 1000;
                break;
        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
                if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
                        ret = -ENODEV;
                else
                        val->intval = battery->voltage_now * 1000;
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
        case POWER_SUPPLY_PROP_POWER_NOW:
                                                                                                                                                                             195,1         15%
rickysarraf commented 8 years ago

@utrack Please try commit id: https://github.com/rickysarraf/laptop-mode-tools/commit/4c5ebb6665cda35bbae4c5361218e7ad9f1afb3a

utrack commented 8 years ago

Thanks for the pointers! It (almost) worked, however with a small fix it works flawlessly. Check out the PR #69 :) I'll report the problem to linux-acpi-dev meanwhile.