Installing apcupsd with USB Support on OmniOS

I installed OmniOS on my home filer over the Christmas break. Jumping from a Solaris Nevada build to OmniOS meant figuring out what software packages are available in the OmniOS repositories, what third-party repos are available and what software I would have to compile by hand. Given that this machine is only acting as a filer and isn’t running any other services to speak of, the list of software to get up and running is small; however a critical component is apcupsd which talks to the Uninterruptible Power Supply (UPS) and cleanly powers down the filer if the power goes out for an extended time.

The hangup for me is that my UPS connects to the filer via USB, not a serial connection. It took me some hours to figure out how to get apcupsd installed with USB support. Here’s how.

These are the basic steps:

  1. Install the developer software packages needed to compile C/C++ code
  2. Install libusb, a prerequisite for apcupsd
  3. Build apcupsd

Why build apcupsd at all? Why not install a binary package? I tried.

Tried Outcome
Install from OmniOS pkg repository apcupsd not present in repo
Install from OmniTI’s non-core package repo apcupsd not present in repo
Install from a listed third-party repo apcupsd not present in any third-party repo
Install from the OpenIndiana pkg repo apcupsd not present in repo
Install a binary package from OpenCSW OpenCSW has an apcupsd package, however you can see by inspecting their Makefile that they do not build it with USB support

Building from source was really the only option left.

UPDATE Aug 29, 2013: I thought building from source was the only option left but Ed Begley pointed out that libusb and libusbugen are available in the OpenIndiana /hipster repo at http://pkg.openindiana.org/hipster

Install Developer Software

Being somewhat of a bare-bones OS, OmniOS doesn’t install developer tools by default.

Note that this is somewhat untrue. While the OmniOS philosophy is to keep the OS lightweight, there is a small bug in the 151004 release that causes the gcc44 package to be installed by default.  (http://omnios.omniti.com/ticket.php/42)

The OmniOS Wiki details how to install the dev packages in one shot. Since gcc44 was already installed on my system I opted not to include the gcc46 package and just rely on gcc44 to get the job done.

# pkg install \
   developer/object-file \
   developer/linker \
   developer/library/lint \
   developer/build/gnu-make \
   system/header \
   system/library/math/header-math

Install libusb

When using a USB-connected UPS, apcupsd depends on a third-party library for talking on the USB bus. Getting libusb installed was the trickiest part of this whole thing for me. Here are the options I explored and why none were successful.

 Option  Outcome
Install from OmniOS pkg repo libusb not present
Install from OmniTI’s non-core repo or a listed third-party repo libusb not present
Install from OpenIndiana pkg repo libusb is present in this repo, however it depends on the SFW consolidation which contains a whole lot of software that isn’t necessary on a filer and that I didn’t want to install (almost 800 packages including things like PostgreSQL, Java, and PHP)
Install from OpenCSW No libusb package available
Build from source libusb 1.0 does not support Solaris
Build OpenUSB which is a fork of libusb and offers support for Solaris When ./configuring libopenusb, it looks for an installed copy of libusb. Yes, really.

This is where I got stumped and started going around in circles, trying lots of Google searches, and trying to make sure I hadn’t overlooked something. Then by fluke, a random Google search turned me on to an SRV4 package named SUNWlibusb. This package happened to be on the Solaris Nevada ISO and had zero dependencies. Perfect.

# lofiadm -a /Solaris/Solaris_Nevada_b129/sol-nv-b129-x86-dvd.iso
/dev/lofi/1
# mount -F hsfs /dev/lofi/1 /media
# ls -ld /media/Solaris_11/Product/SUNWlibusb*
/media/Solaris_11/Product/SUNWlibusb
/media/Solaris_11/Product/SUNWlibusbugen

There we go, the two packages needed to get USB support in apcupsd. Thankfully, OmniOS ships with the SRV4 package management tools so it was very simple to install them.

# pkgadd -d /media/Solaris_11/Product SUNWlibusb SUNWlibusbugen

One last but very important step: you must perform a reconfiguration reboot after installing libusbugen. This will force the UPS to attach to the ugen(7D) driver rather than the hid(7D) driver (which it does by default).

# touch /reconfigure
# shutdown -y -g0 -i6

If the UPS does not attach to the ugen(7D) driver at system boot, apcupsd will not be able to detect the UPS.

You can verify where your UPS has attached by looking at the system boot messages in /var/adm/messages. This is attached to hid(7D) (what we don’t want):

[...] usba: [ID 912658 kern.info] USB 1.10 device (usb51d,2) operating at low speed (USB 1.x) on USB 1.10 root hub: input@1, hid0 at bus address 2
[...] usba: [ID 349649 kern.info]     American Power Conversion Back-UPS XS 1300 LCD FW:836.H8 .D USB FW:H8  BB0847008412

This is attached to ugen(7D) (exactly what we want):

[...] usba: [ID 912658 kern.info] USB 1.10 device (usb51d,2) operating at low speed (USB 1.x) on USB 1.10 root hub: input@1, ugen0 at bus address 2
[...] usba: [ID 349649 kern.info]   American Power Conversion Back-UPS XS 1300 LCD FW:836.H8 .D USB FW:H8  BB0847008412

If you have multiple USB devices on your system, look for usb51d,2 — it’s the vendor code for APC.

Build apcupsd

I like binaries for third-party software installed under /usr/local/{bin,sbin}, config files in /etc and logs in /var/log. This is how I ran ./configure:

./configure \
  --prefix=/usr/local \
  --sbindir=/usr/local/sbin \
  --sysconfdir=/etc/apcupsd \
  --mandir=/usr/local/share/man \
  --with-log-dir=/var/log \
  --disable-cgi \
  --enable-usb

For some reason, setting –prefix is not enough. I had to also set –sbindir and –mandir.

Once configure is done, “gmake install” takes care of the rest and we end up with a working apcupsd:

# /usr/local/sbin/apcaccess
APC      : 001,036,0902
DATE     : 2013-01-01 10:27:52 -0700
HOSTNAME : sigma
VERSION  : 3.14.10 (13 September 2011) sun
UPSNAME  : sigma
CABLE    : USB Cable
DRIVER   : USB UPS Driver
[...]

 

15 thoughts on “Installing apcupsd with USB Support on OmniOS”

  1. Can you provide a link to download the relevant packages? The oldest version I could find on Oracle’s site was this sol-10-u10-ga2-x86-dvd.iso. When I tried to follow your steps with that, I couldn’t apcupsd to make properly, I keep getting this error.

    In file included from hidutils.c:28:0:
    libusb.h:9:17: fatal error: usb.h: No such file or directory
    compilation terminated.

    1. Hi,

      usb.h is provided by the SUNWlibusb package. Looks like maybe it’s missing or the version from Sol10u10 didn’t put files in the right spot or didn’t include that file. Who knows.

      The OKC Solaris Users Group has some OpenSolaris ISOs online (http://okcosug.org/). Pull down the ISO and install SUNWlibusb and SUNWlibusbugen from there and see if that works any better.

  2. Thanks for trying to help. Unfortunately, none of those isos contain a Platform directory, or the SUNWlibusb libs. I’ll keep trying to find the iso you used.

    1. It’s Product not Platform.

      That directory is there for sure. Sun didn’t change directory structures between releases. Check the instructions carefully against what you’re doing.

  3. HI,
    I’m a little late to the party, but I have a problem with getting the UPS to attach via ugen driver. I’ve installed SUNWlibusb and SUNWlibusbugen from nevada b130 ISO, and I touch /reconfigure, but after every reboot the UPS attaches to the hid driver. Any suggestion?

    1. I found some help over here:
      http://barbz.com.au/blog/?p=407

      First up I had to change the driver [OmniOS] allocated to this device from a HID driver to a UGEN
      1. Run #prtconf -v and look for your usb device – I dumped this into a text file and searched for [“Back-UPS” or “1500” since I have a model XS-1500]
      2. Remove the ugen driver from memory #rem_drv ugen
      3. Force the device to load with the ugen driver (find the address of the usb device from step 1)
      #add_drv -i ‘”usb665,5161.2″‘ -m ‘* 0666 root sys’ ugen

      4. Done – check the device is a ugen device either through #prtconf -D or #dmesg | grep ugen

  4. No problem.
    One correction : specifically, in step 3 the USB address should be “usb51d,2.106”
    sudo /usr/sbin/add_drv -i ‘”usb51d,2.106″‘ -m ‘* 0666 root sys’ ugen

    Also, I found a user who posted the same thing over here in 2009:
    http://www.xenorg.com/?p=36

    Lastly, for anyone else (including myself) in future space time, Joel left out two steps in the “Build apcupsd” section of this tutorial.
    1) After you make install, you need to first configure a couple settings in /etc/apcupsd/apcupsd.conf … there are plenty of examples on the web.
    2) you need to start the daemon before you can test its status (last step of this tutorial).
    # /etc/init.d/apcupsd start
    # /etc/init.d/apcupsd status

    I am running apcupsd-3.4.10 on OmniOS stable with an APC Back-UPS XS-1500

  5. The gmake totally failed.

    /opt/csw/apc/apcupsd-3.14.14> gmake
    src
    src/lib
    CXX src/lib/apcconfig.c
    CC: Warning: Option -x passed to ld, if ld is invoked, ignored otherwise
    CC: Warning: Option -fno-exceptions passed to ld, if ld is invoked, ignored otherwise
    CC: Warning: Option -fno-rtti passed to ld, if ld is invoked, ignored otherwise
    “/opt/csw/apc/apcupsd-3.14.14/include/getopt.h”, line 111: Error: Only one of a set of overloaded fu nctions can be extern “C”.
    “/opt/csw/apc/apcupsd-3.14.14/include/struct.h”, line 66: Warning: Identifier expected instead of “} “.
    “/opt/csw/apc/apcupsd-3.14.14/include/struct.h”, line 73: Warning: Identifier expected instead of “} “.
    “/opt/csw/apc/apcupsd-3.14.14/include/struct.h”, line 79: Warning: Identifier expected instead of “} “.
    “apcconfig.c”, line 672: Warning: Too few arguments in macro Error_abort.
    “apcconfig.c”, line 672: Error: Trailing comma in a parameter list.
    “apcconfig.c”, line 709: Warning: Too few arguments in macro Error_abort.
    “apcconfig.c”, line 709: Error: Trailing comma in a parameter list.
    “apcconfig.c”, line 717: Warning: Too few arguments in macro Error_abort.
    “apcconfig.c”, line 717: Error: Trailing comma in a parameter list.
    4 Error(s) and 6 Warning(s) detected.
    gmake[3]: *** [../../autoconf/targets.mak:148: .obj/apcconfig.o] Error 2
    gmake[2]: *** [../../autoconf/targets.mak:55: all] Error 2
    gmake[1]: *** [../autoconf/targets.mak:111: lib_DIR] Error 2
    gmake: *** [autoconf/targets.mak:111: src_DIR] Error 2

Leave a Reply

Your email address will not be published. Required fields are marked *

Would you like to subscribe to email notification of new comments? You can also subscribe without commenting.