[Nut-upsdev] [PATCH] disable nonblocking mode on serial port

Arjen de Korte nut+devel at de-korte.org
Fri Sep 26 05:36:56 UTC 2008


Citeren "Jim Paris" <jim at jtan.com>:

> I got a new Cyberpower 1500AVR UPS and nut wouldn't work.  It failed
> to detect the UPS and a strace showed that all writes to the serial
> port were failing with -EAGAIN.  The attached patch disabled
> nonblocking mode on the serial port and now it works fine.

What operating system are you using? Which NUT driver? If you're using  
the 'cyberpower' driver, switch to the 'powerpanel' driver and you can  
probably skip the remainder of this message.

The thing you should ask yourself is why the connection is timing out  
in the first place. Running the driver in debug mode might reveal what  
is going on. If it is because we are sending it too much data and the  
UPS can't keep up with the data flow, this should be fixed. The same  
may happen if synchronization is lost, which is a frequent problem  
with drivers that don't properly flush in- and outputs.

Using the sledgehammer approach of opening the device in blocking mode  
and just sit it out until it can handle whatever we throw at it is  
definitely not what we want and certainly not something that we will  
integrate into NUT without ruling out the problems already mentioned.

> Is there a reason the port was put in non-blocking mode?

Of course. :-)

> There's no
> code I could find to deal with the inevitable -EAGAIN that you'd
> receive on writes.  Maybe the delays introduced by ser_send_pace are
> why it might work for some people?

Opening a port in non-blocking mode allows us to deal with errors that  
we may encounter (in a timely manner). If you open a device in  
blocking mode, it may take a relatively long time before we notice  
that something is wrong for some error conditions. The timeout depends  
on the system settings, but 15 minutes is not uncommon.

While this will be dealt with while reading data (through select()  
calls, so these never risk blocking), this is not the case when  
writing to the device. If the UPS happens to be on battery at that  
time, it will probably be empty by the time the call times out and the  
system will be shutdown hard.

Your patch makes little sense, since just removing O_NONBLOCK from the  
flags in the call to open() should be sufficient already. However, if  
we should ever decide that in order to use the Cyberpower 1500AVR UPS  
we need to open it in blocking mode, clearing the O_NONBLOCK flag  
should be done by the driver. By doing it here, you risk breaking all  
other drivers that use this library.

Best regards, Arjen
-- 
Please keep list traffic on the list



More information about the Nut-upsdev mailing list