Skip to content

CI only: #2021 fix plus regression test (expected to pass) - #2

Open
cgoudie wants to merge 4 commits into
developfrom
fix/stopdiscovery-inprogress
Open

CI only: #2021 fix plus regression test (expected to pass)#2
cgoudie wants to merge 4 commits into
developfrom
fix/stopdiscovery-inprogress

Conversation

@cgoudie

@cgoudie cgoudie commented Sep 3, 2026

Copy link
Copy Markdown

Demonstration run for hbldh#2022: the fix and the regression test together. The BlueZ integration job is expected to PASS. Not for merge; the real PR is upstream.

InProgress on StopDiscovery is bluetoothd relaying MGMT_STATUS_REJECTED
from the kernel, which it returns when discovery is already not active.
bluetoothd removes the client's discovery session before replying, so by
the time bleak sees the error there is nothing left to stop; raising only
turns a completed scan into an exception the caller cannot retry, since
the scanner nulls _stop before awaiting it.

The usual trigger is the kernel's own LE scan timeout: an LE-only scan is
stopped after DISCOV_LE_TIMEOUT (10.24 s) and re-armed by bluetoothd
IDLE_DISCOV_TIMEOUT (5 s) later, and a stop landing in that gap is
rejected. find_device_by_address with a 15 s timeout on an absent device
hits it essentially every time on BlueZ 5.72.

Treat it like NotReady, which this branch already swallows. The
integration test scans for 12 s so that the stop lands inside the gap.

Fixes hbldh#2021
…n the test

The kernel rejects StopDiscovery whenever it is not actively scanning,
which includes the moments while BlueZ is restarting the scan after the
kernel's own LE timeout, not only after it has stopped. In the idle gap
itself BlueZ already knows the kernel is idle and stops cleanly, so the
window is narrow and the failure is intermittent in the field. The test
now stops at several points around the restart instead of one.
It cannot fail on unpatched code. The rejection needs bluetoothd to
forward a stop after the kernel has left the FINDING state but before
bluetoothd has processed the kernel's Discovering(false) event, and on a
healthy system that window is a scheduling race, not a time offset:
stops at 10, 12, 15, 15.2, 15.4 and 16 s after start were accepted 18 of
18 times on BlueZ 5.72, as were five find_device_by_address timeouts.
The in-field occurrences (24 in one day) were under a crash-looping
bluetoothd and have not recurred since it was fixed.
…he BlueZ path in the comment

A faked-reply test rather than an integration test, because the condition
cannot be produced on demand: bluetoothd only forwards a client's stop to
the kernel while its own discovery_enable flag is set, and it clears that
flag when it processes the kernel's Discovering(false) event, so the
kernel's rejection needs a stop to land in the gap between the two. That
is a scheduling race, not a time offset a test can aim at; on BlueZ 5.72
stops at 10, 12, 15, 15.2, 15.4 and 16 s after start were accepted 18 of
18 times. The test fakes the bus reply and pins bleak's handling: stop()
returns, the callbacks are removed, and any other error still raises.

The code comment now names the bluetoothd path (stop_discovery_complete
removes the session before checking the status, then relays
MGMT_STATUS_REJECTED as InProgress), as requested in the review.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant