Prev |  | Next

## 12. NUT core development and maintenance

This section is intended to people who want to develop new core features, or to do some maintenance.

### 12.1. NUT-specific autoconf macros

The following NUT-specific autoconf macros are defined in the `m4/` directory.

NUT_TYPE_SOCKLEN_T , NUT_TYPE_UINT8_T , NUT_TYPE_UINT16_T
  Check for the corresponding type in the system header files, and `#define` a replacement if necessary.
NUT_CHECK_LIBGD , NUT_CHECK_LIBNEON , NUT_CHECK_LIBNETSNMP , NUT_CHECK_LIBPOWERMAN , NUT_CHECK_LIBOPENSSL , NUT_CHECK_LIBNSS , NUT_CHECK_LIBUSB , NUT_CHECK_LIBWRAP , et al

  Determine the compiler flags for the corresponding library. On success, set `nut_have_libxxx="yes"` and set `LIBXXX_CFLAGS` and `LIBXXX_LDFLAGS`. On failure, set `nut_have_libxxx="no"`. This macro can be run multiple times, but will do the checking only once. Here "xxx" should of course be replaced by the respective library name.

  The checks for each library grow organically to compensate for various bugs in the libraries, pkg-config, etc. This is why we have a separate macro for each library.

NUT_CHECK_IPV6

  Check for various features required to compile the IPv6 support. Define a preprocessor symbol for each individual feature (`HAVE_GETADDRINFO`, `HAVE_FREEADDRINFO`, `HAVE_STRUCT_ADDRINFO`, `HAVE_SOCKADDR_STORAGE`, `SOCKADDR_IN6`, `IN6_ADDR`, `HAVE_IN6_IS_ADDR_V4MAPPED`, `HAVE_AI_ADDRCONFIG`).

  Also set the shell variable `nut_have_ipv6=yes` if all the required features are present. Set `nut_have_ipv6=no` otherwise.

NUT_CHECK_OS
  Check for the exact system name and type. This was only used in the past to determine the packaging rule to be used through the `OS_NAME` variable, but may be useful for other purposes in the future.
NUT_REPORT_FEATURE(FEATURE, VALUE, VARIABLE, DESCRIPTION)

  Schedule a line for the end-of-configuration feature summary. The FEATURE is a descriptive string such that the sentence "Checking whether to FEATURE" makes sense, and VALUE describes the decision taken (typically yes or no). The feature is also reported to the terminal.

  Also use VARIABLE and DESCRIPTION for defining `AM_CONDITIONAL` and `AC_DEFINE` (only if `VALUE = "yes"`). The VARIABLE is of the form `WITH_<NAME>`.

NUT_REPORT(FEATURE, VALUE)
  Schedule a line for the end-of-configuration feature summary, without printing anything to the terminal immediately.
NUT_PRINT_FEATURE_REPORT
  Print out a list of the features that have been reported by previous `NUT_REPORT_FEATURE` macro calls.
NUT_ARG_WITH(FEATURE, DESCRIPTION, DEFAULT)
  Declare a simple `--with-FEATURE` option with the given DESCRIPTION and DEFAULT. Sets the variable `nut_with_FEATURE`.

### 12.2. NUT roadmap and ideas for future expansion

Here are some ideas that have come up over the years but haven’t been implemented yet. This may be a good place to start if you’re looking for a rainy day hacking project.

#### Roadmap

##### 2.6

This release is focused on the website and documentation rewrite, using the excellent AsciiDoc.

##### 2.8

This branch will focus on configuration and user interface improvements.

##### 3.0

This major transition will mark the final switch to a complete power device broker.

#### Non-network "upsmon"

Some systems don’t want a daemon listening to the network. This can be for security reasons, or perhaps because the system has been squashed down and doesn’t have TCP/IP available. For these situations you could run a driver and program that sits on top of the driver socket to do local monitoring.

This also makes monitoring extremely easy to automate - you don’t need to worry about usernames, passwords or firewalling. Just start a driver and drop this program on top of it.

- Parse ups.conf and open the state socket for a driver
- Send DUMPALL and enter a select loop
- Parse SETINFOs that change ups.status
- When you get OB LB, shut down

#### Completely unprivileged upsmon

upsmon currently retains root in a forked process so it can call the shutdown command. The only reason it needs root on most systems is that only privileged users can signal init or send a message on /dev/initctl.

In the case of systems running sysvinit (Slackware, others?), upsmon could just open /dev/initctl while it has root and then drop it completely. When it’s time to shut down, fire a control structure at init across the lingering socket and tell it to enter runlevel 0.

This has been shown to work in local tests, but it’s not portable. It could only be offered as an option for those systems which run that flavor of init. It also needs to be tested to see what happens to the lingering fd over time, such as when init restarts after an upgrade.

For other systems, there is always the possibility of having a suid program which does nothing but prod init into starting a shutdown. Lock down the group access so only upsmon’s unprivileged user can access it, and make that your SHUTDOWNCMD. Then it could drop root completely.

#### Chrooted upsmon

upsmon could run the network monitoring part in a chroot jail if it had a pipe to another process running outside for NOTIFY dispatches. Such a pipe would have to be constructed extremely carefully so an attacker could not compromise it from the jailed process.

A state machine with a tightly defined sequence could do this safely. All it has to do is dispatch the UPS name and event type.

    [start] [type] [length] <name> [stop]

#### Monitor program with interpreted language

Once in awhile, I get requests for a way to shut down based on the UPS temperature, or ambient humidity, or at a certain battery charge level, or any number of things other than an "OB LB" status. It should be obvious that adding a way to monitor all of that in upsmon would bloat upsmon for all those people who really don’t need anything like that.

A separate program that interprets a list of rules and uses it to monitor the UPS equipment is the way to solve this. If you have a condition that needs to be tested, add a rule.

Some of the tools that such a language would need include simple greater-than/less-than testing (if battery.charge < 20), equivalence testing (if ups.model = "SMART-UPS 700"), and some way to set and clear timers.

Due to the expected size and limited audience for such a program, it might have to be distributed separately.

### Note

Python may be a good candidate.

#### Sandbox

- check to refresh and integrate the tasks list and feature requests list from Alioth
- add "Generic ?Ascii? driver": I’ve got to think more about that, but the recent solar panel driver, and the powerman internal approach of a generic engine with a scripting interface is a cool idea. Ref http://powerman.svn.sourceforge.net/viewvc/powerman/trunk/etc/apcpdu.dev?revision=969&view=markup
- integrate the (future) new powerman LUA engine (maybe/must-be used for the driver above?) for native PDU support
- see how we can help and collaborate with DeviceKit-power

Prev |  | Next
| Home |