Bug 79941

Summary: bluetoothd won't read stored device key upon restart
Product: Drivers Reporter: Aleksei Kaveshnikov (4nykey)
Component: BluetoothAssignee: linux-bluetooth (linux-bluetooth)
Status: NEW ---    
Severity: normal CC: johan.hedberg, pachoramos1, s.rasnikov, szymon.janc
Priority: P1    
Hardware: x86-64   
OS: Linux   
Kernel Version: 3.14.11 Subsystem:
Regression: No Bisected commit-id:
Attachments: changes to src/adapter.c
fallback to lstat
Alternate patch

Description Aleksei Kaveshnikov 2014-07-10 20:05:34 UTC
After daemon restart, previously added device won't reconnect.

Reproducible: Always

Steps to Reproduce:
1. Add a BT device (tested with Logitech M555b mouse via bluetoothctl pair-trust-connect)
2. Restart bluetoothd

Actual Results:
Added device won't reconnect

Expected Results:  
Previously added device will restore connection

The device key is present in '/var/lib/bluetooth/<adapter:addr>/<device:addr>/info' under [LinkKey].

When I restart bluetoothd (hibernate/thaw, manual daemon or system restart), running '/usr/libexec/bluetooth/bluetoothd -dn' will produce:

> src/adapter.c:load_link_keys() hci0 keys 0 debug_keys 0

When I'll move the mouse I'll get these lines in syslog:

> bluetoothd[1234]: Refusing input device connect: No such file or directory
> (2)
> bluetoothd[1234]: Refusing connection from xx:xx:xx:xx:xx:xx: unknown device

Then '/var/lib/bluetooth/<adapter:addr>/<device:addr>/info' will be removed and recreated with an other key, if I'll add the mouse again.
Comment 1 Aleksei Kaveshnikov 2014-07-10 20:08:11 UTC
Created attachment 142661 [details]
changes to src/adapter.c

If I change src/adapter.c like this, bluetoothd will read the stored key and connect to the device:

> src/adapter.c:load_link_keys() hci0 keys 1 debug_keys 0
Comment 2 Johan Hedberg 2014-07-10 20:31:33 UTC
The DT_DIR check is supposed to ensure that '/var/lib/bluetooth/<adapter:addr>/<device:addr>/' is a directory. Your patch seems to change the code to skip any entries under '/var/lib/bluetooth/<adapter:addr>/' that are *not* directories. Can you explain why that fixes the issue for you? (since otherwise the patch looks wrong to me).
Comment 3 Szymon Janc 2014-07-10 22:46:18 UTC
This could happen if filesystem doesn't support d_type. In such case d_type is DT_UNKNOWN and we shoud handle that. With attached patch bluetoothd will fallback to lstat().

Aleksei, could you test if this solves your problem?
Comment 4 Szymon Janc 2014-07-10 22:48:43 UTC
Created attachment 142671 [details]
fallback to lstat
Comment 5 Johan Hedberg 2014-07-11 07:22:15 UTC
Created attachment 142711 [details]
Alternate patch

DT_UNKNOWN could indeed be the cause of this, but I'd avoid modifying the already largish loop by having a helper function for the lstat call. Either way it'd be good to know if one of the patches fixes the issue. It'd also be good to know exactly what kind of setup you have (libc version, kernel version, filesystem type, etc).

Some unrelated notes: PATH_MAX already contains the terminating null so +1 is unnecessary. Also, snprintf (unlike strncpy) guarantees a terminating null so no need to force that after the call. Both of these issues should probably be fixed in many places of the code base.
Comment 6 Aleksei Kaveshnikov 2014-07-11 08:19:08 UTC
(In reply to Szymon Janc from comment #3)
> This could happen if filesystem doesn't support d_type.

Appears to be the case, my /var is on reiserfs.

Didn't insist the patch is correct, it was merely RFC. Will check proposed patches shortly.
Comment 7 Aleksei Kaveshnikov 2014-07-11 08:32:43 UTC
(In reply to Johan Hedberg from comment #5)
> It'd also be
> good to know exactly what kind of setup you have (libc version, kernel
> version, filesystem type, etc).

See here: https://516600.bugs.gentoo.org/attachment.cgi?id=380364
Comment 8 Aleksei Kaveshnikov 2014-07-11 08:39:37 UTC
Both patches in attachment 142671 [details] and attachment 142711 [details] fix the issue
Comment 9 Szymon Janc 2014-08-26 09:12:15 UTC
Fixed in BlueZ 5.22