[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