If a device is indexed (for example, a wired ethernet connection), it
can be successfully enabled by calling connman_inet_ifup(). This means
that the call to device->driver->enable() lower down in
__connman_device_enable() will fail with EALREADY. Squash that error,
since the overall operation has been a success.

This can be reproduced on a system with a wired connection using
connmanctl:
    $ connmanctl technologies
    /net/connman/technology/ethernet
      Name = Wired
      Type = ethernet
      Powered = True
      Connected = True
      Tethering = False
    $ connmanctl disable ethernet
    Disabled ethernet
    $ connmanctl technologies
    /net/connman/technology/ethernet
      Powered = False
      …
    $ connmanctl enable ethernet
    Error ethernet: Already enabled

With the patch applied, the final call succeeds as expected.
---
 src/device.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/device.c b/src/device.c
index c0683ab..c9e9b8b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -168,7 +168,7 @@ static gboolean device_pending_reset(gpointer user_data)
 
 int __connman_device_enable(struct connman_device *device)
 {
-       int err;
+       int err, index_err = -EOPNOTSUPP;
 
        DBG("device %p", device);
 
@@ -186,9 +186,9 @@ int __connman_device_enable(struct connman_device *device)
                return -EALREADY;
 
        if (device->index > 0) {
-               err = connman_inet_ifup(device->index);
-               if (err < 0 && err != -EALREADY)
-                       return err;
+               index_err = connman_inet_ifup(device->index);
+               if (index_err < 0 && index_err != -EALREADY)
+                       return index_err;
        }
 
        device->powered_pending = PENDING_ENABLE;
@@ -197,9 +197,14 @@ int __connman_device_enable(struct connman_device *device)
        /*
         * device gets enabled right away.
         * Invoke the callback
+        *
+        * If device->driver->enable() returned EALREADY but the earlier
+        * connman_inet_ifup() call did not, then the interface came up
+        * with the earlier call and we should not report an error.
         */
-       if (err == 0) {
+       if (err == 0 || (err == -EALREADY && index_err == 0)) {
                connman_device_set_powered(device, true);
+               err = 0;
                goto done;
        }
 
-- 
1.9.3

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman

Reply via email to