Package: apcupsd
Version: 3.14.10-1
Severity: normal

Dear Maintainer,

After an upgrade, I found that apcupsd would consistently die within
a few seconds of starting. I use it to monitor a Smart-UPS 700 with
an old AP9606 management card over SNMP. The init script did not
report an error, and there was nothing in syslog to indicate the
cause of the failure.

When I ran apcupsd manually on the command line, with the -b option,
it dumped out some SNMP-related debugging information reflecting the
MIB structure, but still no error message.

I tried the alternative "netsnmp" UPSTYPE, marked "OBSOLETE" in the
sample apcupsd.conf, but it seems that is not supported:


Apcupsd driver snmp not found.
The available apcupsd drivers are:
dumb
apcsmart
net
usb
snmplite
test
pcnet

Most likely, you need to add --enable-snmp to your ./configure options.

apcupsd FATAL ERROR in apcupsd.c at line 259
Apcupsd cannot continue without a valid driver.


My next step was to rebuild the package with debugging symbols and run
it under gdb.

Program received signal SIGABRT, Aborted.
0x00007ffff744f405 in *__GI_raise (sig=<optimized out>) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:64
64      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
        in ../nptl/sysdeps/unix/sysv/linux/raise.c
(gdb) bt
#0  0x00007ffff744f405 in *__GI_raise (sig=<optimized out>) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff7452680 in *__GI_abort () at abort.c:92
#2  0x00000000004209d2 in astring::operator[] (this=<optimized out>, 
index=<optimized out>) at astring.cpp:106
#3  0x0000000000418731 in apc_update_ci (ups=0x656010, ci=<optimized out>, 
data=...) at apc-mib.cpp:310
#4  0x0000000000410c45 in snmplite_ups_update_cis (ups=0x656010, dynamic=true) 
at snmplite.cpp:378
#5  0x0000000000411361 in snmplite_ups_read_volatile_data (ups=0x656010) at 
snmplite.cpp:393
#6  0x0000000000404683 in fillUPS (ups=0x656010) at device.c:179
#7  do_device (ups=<optimized out>) at device.c:188
#8  0x0000000000403d26 in main (argc=<optimized out>, argv=0x7fffffffb3a8) at 
apcupsd.c:321

A little investigation found the bug in apc_update_ci(), specifically
the CI_Overload case:

   case CI_Overload:
      Dmsg1(80, "Got CI_Overload: %c\n", data.str[8]);
      if (data.str[8] == '1')
         ups->set_overload();
      else
         ups->clear_overload();
      break;

data.str[8] caused astring::operator[] to abort(), because the string
was actually empty:

(gdb) p data
$3 = (Snmp::Variable &) @0x65fd98: {type = 4 '\004', i32 = 48, u32 = 
4294947488, str = {_data = 0x65fde0 "", _len = 0}, seq = {_vptr.alist = 
0x42f770, _head = 0x0, _tail = 0x0, _size = 0}}

A comment earlier in apc_mib.cpp is revealing:

   // These 5 collectively are used to obtain the data for CI_STATUS.
   // All bits are available in upsBasicStateOutputState at once but 
   // the old AP960x cards do not appear to support that OID, so we use 
   // it only for the overload flag which is not available elsewhere.

I have an AP9606 card, so that is presumably why it is getting an empty
string. (Even for newer ones, the MIB mentions that the management card
may return "UNKNOWN" if it cannot obtain the proper value, which would
cause a similar failure.)

I have applied this patch as a workaround:

=====
--- a/src/drivers/snmplite/apc-mib.cpp
+++ b/src/drivers/snmplite/apc-mib.cpp
@@ -307,6 +307,8 @@
       break;
 
    case CI_Overload:
+      if (data.str.len() < 9)
+         break;
       Dmsg1(80, "Got CI_Overload: %c\n", data.str[8]);
       if (data.str[8] == '1')
          ups->set_overload();
=====

I do not know this code well enough to be sure my fix is strictly
correct, but so far it Works For Me.


-- System Information:
Debian Release: wheezy/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'stable'), (500, 'oldstable'), (50, 
'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 3.1.0-1-amd64 (SMP w/12 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages apcupsd depends on:
ii  libc6     2.13-24
ii  libgcc1   1:4.6.2-11
ii  libwrap0  7.6.q-21

Versions of packages apcupsd recommends:
ii  apcupsd-doc  3.14.10-1

Versions of packages apcupsd suggests:
ii  apcupsd-cgi  <none>
ii  udev         175-3

-- Configuration Files:
/etc/apcupsd/apcupsd.conf changed:
UPSCABLE ether
UPSTYPE snmp
DEVICE ******:161:APC:******
LOCKFILE /var/lock
ONBATTERYDELAY 30
BATTERYLEVEL 5
MINUTES 2
TIMEOUT 0
ANNOY 300
ANNOYDELAY 60
NOLOGON disable
KILLDELAY 0
NETSERVER on
NISIP 127.0.0.1
NISPORT 3551
EVENTSFILE /var/log/apcupsd.events
EVENTSFILEMAX 10
UPSCLASS standalone
UPSMODE disable
STATTIME 0
STATFILE /var/log/apcupsd.status
LOGSTATS off
DATATIME 0

/etc/default/apcupsd changed:
APCACCESS=/sbin/apcaccess
ISCONFIGURED=yes


-- no debconf information



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to