Re: [PATCH] adapter: Guard StartDiscovery and StopDiscovery with discovering check

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Luiz,

I am about to implement the async reply for StartDiscovery, then I
realize that there is a case where this may cause dbus timeout if this
happens several times:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/adapter.c#n1456.
Now I am not sure if async reply is suitable for this operation. What
do you think? Thanks.

On Thu, Aug 24, 2017 at 12:11 PM, Sonny Sasaka <sonnysasaka@xxxxxxxxxxxx> wrote:
> Hi Luiz,
>
> On Thu, Aug 24, 2017 at 1:30 AM, Luiz Augusto von Dentz
> <luiz.dentz@xxxxxxxxx> wrote:
>> Hi,
>>
>> On Thu, Aug 24, 2017 at 2:55 AM,  <mcchou@xxxxxxxxxxxx> wrote:
>>> From: Miao-chen Chou <mcchou@xxxxxxxxxxxx>
>>>
>>> There is a race condition where a start/stop discovery is requested before the
>>> previous stop/start discovery finish, and checking the adapter->discovery_list
>>> is insufficient to guard to race condition. For example, if start_discovery is
>>> called right after stop discovery, the callback, stop_discovery_complete, may
>>> not be called before calling start_discovery. Then start_discovery will
>>> proceed and fail.
>>>
>>> Test steps:
>>> Add delay in kernel for the stop discovery callback.
>>> Check if the start discovery can happen before the completion of the previous
>>> stop discovery, and the other way around.
>>>
>>> Please refer to https://bugs.chromium.org/p/chromium/issues/detail?id=738237
>>> for more details.
>>
>> It is giving me:
>>
>> You do not have permission to view the requested page.
>>
>> Reason: User is not allowed to view this issue
>>
>>> ---
>>>  src/adapter.c | 26 +++++++++++++++++++++++---
>>>  1 file changed, 23 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/src/adapter.c b/src/adapter.c
>>> index 83f38ddbe..395b430d2 100644
>>> --- a/src/adapter.c
>>> +++ b/src/adapter.c
>>> @@ -2119,20 +2119,30 @@ static DBusMessage *start_discovery(DBusConnection *conn,
>>>         struct btd_adapter *adapter = user_data;
>>>         const char *sender = dbus_message_get_sender(msg);
>>>         struct watch_client *client;
>>> -       bool is_discovering;
>>> +       bool discovery_client_exists;
>>
>> Don't really see why to change the name here.
>
> It's to prevent confusion between is_discovering and
> adapter->discovering. But we can modify to follow your preference.
>
>>
>>>         DBG("sender %s", sender);
>>>
>>>         if (!(adapter->current_settings & MGMT_SETTING_POWERED))
>>>                 return btd_error_not_ready(msg);
>>>
>>> -       is_discovering = get_discovery_client(adapter, sender, &client);
>>> +       discovery_client_exists = get_discovery_client(
>>> +                       adapter, sender, &client);
>>>
>>>         /*
>>>          * Every client can only start one discovery, if the client
>>>          * already started a discovery then return an error.
>>>          */
>>> -       if (is_discovering)
>>> +       if (discovery_client_exists)
>>> +               return btd_error_busy(msg);
>>> +
>>> +       /*
>>> +        * adapter->discovery_list being empty but adapter->discovering being
>>> +        * true indicates that there is a stop discovery operation in progress.
>>> +        * Prevent a new start discovery request when the previous
>>> +        * stop discovery is in progress.
>>> +        */
>>> +       if (!adapter->discovery_list && adapter->discovering)
>>
>> Perhaps we should delay the removal of a client if it is the last in
>> the list, or actually both start and stop discovery need to wait their
>> respective commands to complete before replying, that way the client
>> can actually be sure it has started or stopped the discovery and we
>> don't have to reply busy.
>
> I agree that we can wait to reply after the command is completed. But I think
> we still need the busy error in case the client doesn't honor the
> "wait until dbus reply"
> protocol, otherwise bluetoothd will enter into a strange internal
> state if it's not guarded.
> What do you think?
>
>>
>>>                 return btd_error_busy(msg);
>>>
>>>         /*
>>> @@ -2420,6 +2430,16 @@ static DBusMessage *stop_discovery(DBusConnection *conn,
>>>         if (!list)
>>>                 return btd_error_failed(msg, "No discovery started");
>>>
>>> +       /*
>>> +        * adapter->discovery_list being not empty but adapter->discovering
>>> +        * being false indicates that there is a start discovery operation in
>>> +        * progress.
>>> +        * Prevent a new stop discovery request when the previous start
>>> +        * discovery is in progress.
>>> +        */
>>> +       if (!adapter->discovering)
>>> +               return btd_error_busy(msg);
>>
>> Ditto.
>>
>>>         client = list->data;
>>>
>>>         cp.type = adapter->discovery_type;
>>> --
>>> 2.14.1.342.g6490525c54-goog
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>>
>>
>> --
>> Luiz Augusto von Dentz
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux