Re: [PATCH] device: Don’t report EALREADY if enabling device succeeds with ifup

2015-03-19 Thread Patrik Flykt
On Wed, 2015-03-18 at 17:06 +, Philip Withnall wrote:
 Whew, right. I am unlikely to find time to work on this until one or
 three weeks from now, but I have put it on my backlog to look at as
 soon as I can after then. Sorry!

No problem. Thanks for taking time to report the issue and solving it at
least in one way - it works that way too actually.

The only issue I have is that there is a bigger risk of someone
forgetting what errors devices should or should not return, thus the
proposed more generic task of figuring out what response is appropriate
from the technology API. Doing it quickly makes me believe that
-EALREADY should be treated as success (= 0), but the details matter.
I'll look into this a bit.

Cheers,

Patrik



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


Re: [PATCH] device: Don’t report EALREADY if enabling device succeeds with ifup

2015-03-18 Thread Philip Withnall
On Mon, 2015-03-16 at 12:58 +0200, Patrik Flykt wrote:
 On Fri, 2015-03-13 at 08:31 +, Philip Withnall wrote:
  $ connmanctl disable ethernet
  Disabled ethernet
  $ connmanctl technologies
  /net/connman/technology/ethernet
Powered = False
…
  $ connmanctl enable ethernet
  Error ethernet: Already enabled
 
 Did anything special happen between checking that the Powered status was
 False and enabling it again? Did 'monitor technologies' show Powered
 changing state in between?

Nope, nothing changed in between.

  ---
   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;
  }
 
 This check is a bit too low in the stack. In device.c it is ok to report
 -EALREADY for situations that are already in the state they're attempted
 to be set to.
 
 There are actually two bugs in technology.c.
 
 The first bug is in technology_enable(), once past the statement 'if
 (technology-enabled)...' there is no reason to reply with -EALREADY.
 For some reason ConnMan's powered property doesn't reflect the reality
 correctly, but it does not really matter as being a cause for -EALREADY.
 So the first fix is to set err to zero in case of an -EALREADY from
 either __connman_rfkill_block() or technology_affect_devices() before
 returning.
 
 The second bug is in technology_affect_devices(). Only when all affected
 devices report an error should technology_affect_devices() return an
 error, not the result from the device that happens to be the last one in
 the list and fail as is happening now.
 
 An then an additional bug is in technology_disable(), it does the same
 thing wrong as technology_enable()...

Whew, right. I am unlikely to find time to work on this until one or
three weeks from now, but I have put it on my backlog to look at as soon
as I can after then. Sorry!

Philip


signature.asc
Description: This is a digitally signed message part
___
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman

Re: [PATCH] device: Don’t report EALREADY if enabling device succeeds with ifup

2015-03-16 Thread Patrik Flykt
On Fri, 2015-03-13 at 08:31 +, Philip Withnall wrote:
 $ connmanctl disable ethernet
 Disabled ethernet
 $ connmanctl technologies
 /net/connman/technology/ethernet
   Powered = False
   …
 $ connmanctl enable ethernet
 Error ethernet: Already enabled

Did anything special happen between checking that the Powered status was
False and enabling it again? Did 'monitor technologies' show Powered
changing state in between?

 ---
  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;
   }

This check is a bit too low in the stack. In device.c it is ok to report
-EALREADY for situations that are already in the state they're attempted
to be set to.

There are actually two bugs in technology.c.

The first bug is in technology_enable(), once past the statement 'if
(technology-enabled)...' there is no reason to reply with -EALREADY.
For some reason ConnMan's powered property doesn't reflect the reality
correctly, but it does not really matter as being a cause for -EALREADY.
So the first fix is to set err to zero in case of an -EALREADY from
either __connman_rfkill_block() or technology_affect_devices() before
returning.

The second bug is in technology_affect_devices(). Only when all affected
devices report an error should technology_affect_devices() return an
error, not the result from the device that happens to be the last one in
the list and fail as is happening now.

An then an additional bug is in technology_disable(), it does the same
thing wrong as technology_enable()...

Good catch!

Cheers,

Patrik

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

[PATCH] device: Don’t report EALREADY if enabling device succeeds with ifup

2015-03-13 Thread Philip Withnall
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


signature.asc
Description: This is a digitally signed message part
___
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman