Public bug reported:

Thinkfan, for some reason, will occasionally send garbage output to
/proc/acpi/ibm/fan, which causes the error to error with invalid
argument, causing thinkfan to crash.

Thinkfan sometimes will work, but other times will not. I do not know
the exact condition to reproduce.

This is due to a really strange bug in the software. I'm not sure I
quite figured it out, but here's an analysis anyway (patch for this at
the end). Note that I only used this in thinkpad fan mode, so idk about
the behaviour with just pwm.

 In the file system.c, the setfan_ibm function is defined as

void setfan_ibm() {
        int ibm_fan, l = strlen(cur_lvl);

        if (unlikely((ibm_fan = open(IBM_FAN, O_RDWR, O_TRUNC)) < 0)) {
                prefix = "\n";
                report(LOG_ERR, LOG_ERR, IBM_FAN ": %s\n", strerror(errno));
                errcnt |= ERR_FAN_SET;
        }
        else {
                if (unlikely(write(ibm_fan, cur_lvl, l) < l)) {
                        prefix = "\n";
                        report(LOG_ERR, LOG_ERR, MSG_ERR_FANCTRL);
                        errcnt |= ERR_FAN_SET;
                }
                close(ibm_fan);
        }
}

Note that it is trying to write `cur_lvl` to `ibm_fan`, which is
/proc/acpi/ibm/fan.

If you look around, you'll realize a couple of things:

1. setfan_ibm() and what not is actually never called directly, it is called 
via config->setfan(), which is also almost never called directly, once in 
thinkpad.c:159, thinkpad.c:42, and system.c:216. There is a macro defined at 
around thinkpad.c:40 known as `set_fan` that also sets the cur_lvl.
2. There are only 2 locations where `cur_lvl` is set: in the `set_fan` macro as 
discussed, once on main before everything boots, and once when we read the 
configuration.

With some printf debugging, you can see once the program boots, it will
first readconfig, which will give cur_lvl a value of "127", which is not
in the format of "level <i>". Sending this to /proc/acpi/ibm/fan will
fail. The code does set the correct limits (config.c:222), but `cur_lvl`
is never changed.

Next, `setfan()` is called directly at thinkfan.c:159, which I believe
usually only happens during first boot. This means `cur_lvl` is never
set to a correct value. For some reason, adding a printf with cur_lvl's
value here results in the string "V". This is what I'm not quite sure
about.

In any case, switching line 159 to the `set_fan` macro works.

** Affects: thinkfan (Ubuntu)
     Importance: Undecided
         Status: New

** Patch added: "0001-Fixed-thinkfan-writing-out-garbage-to-fan-control.patch"
   
https://bugs.launchpad.net/bugs/1494546/+attachment/4460988/+files/0001-Fixed-thinkfan-writing-out-garbage-to-fan-control.patch

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1494546

Title:
  Thinkfan will occasionally send garbage to fan control (setfan_ibm:
  Error writing to /proc/acpi/ibm/fan)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/thinkfan/+bug/1494546/+subscriptions

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to