SIGPWR interrupt - upstart init with powstatd UPS daemon

Will Dickson wbd at caltech.edu
Fri Feb 16 02:04:35 GMT 2007


Hi, I've been trying to get  powstatd to work with the upstart init 
program on ubuntu edgy and have been having some difficulties. I 
verified that powstatd is performing correctly - i.e.,  when the power 
to the UPS is cut powstatd changes the entry in /etc/powerstatus from OK 
to FAIL and sends a SIGPWR interrupt to init. Init is then suppose to 
check the entry in /etc/powerstatus etc. However, I couldn't seem to get 
the upstart init to respond to the SIGPWR interrupt.

I grepped around in the upstart-0.3.5 sources and couldn't find any 
handlers for SIGPWR. Whereas the sysvinit does have a handler for SIGPWR
Am I missing something? Is there a way to make the upstart init work 
with the UPS daemons?


The SIGPWR signal from powstatd is sent to init as follows (this is
from powstatd.c main)
      
        ...

      /* Next write appropriate status indicator to status file
       * (usually /etc/powerstatus) and then signal init. Note
       * that init must already know where to look! Also, if you
       * are running in test mode, don't actually signal init. */
      if (!testMode)
        {
          sfp = fopen (sfile, "w");
          fprintf (sfp, "%s", PSHOW (newStatus));
          fclose (sfp);
          kill (1, SIGPWR);
        }

        ...
 

code from init.c in sysvinit-2.86 for handling SIGPWR is shown here


void process_signals()
{
  CHILD        *ch;
  int        pwrstat;
  int        oldlevel;
  int        fd;
  char        c;

  if (ISMEMBER(got_signals, SIGPWR)) {
    INITDBG(L_VB, "got SIGPWR");
    /* See _what_ kind of SIGPWR this is. */
    pwrstat = 0;
    if ((fd = open(PWRSTAT, O_RDONLY)) >= 0) {
        c = 0;
        read(fd, &c, 1);
        pwrstat = c;
        close(fd);
        unlink(PWRSTAT);
    }
    do_power_fail(pwrstat);
    DELSET(got_signals, SIGPWR);
  }

  ....


Note, PWRSTAT is set to "/etc/powerstatus"
 
The do_power_fail function is as follows


void do_power_fail(int pwrstat)
{
    CHILD *ch;

    /*
     *    Tell powerwait & powerfail entries to start up
     */
    for (ch = family; ch; ch = ch->next) {
        if (pwrstat == 'O') {
            /*
              *    The power is OK again.
              */
            if (ch->action == POWEROKWAIT)
                ch->flags &= ~XECUTED;
        } else if (pwrstat == 'L') {
            /*
             *    Low battery, shut down now.
             */
            if (ch->action == POWERFAILNOW)
                ch->flags &= ~XECUTED;
        } else {
            /*
             *    Power is failing, shutdown imminent
             */
            if (ch->action == POWERFAIL || ch->action == POWERWAIT)
                ch->flags &= ~XECUTED;
        }
    }
}

you can see where the powerokwait, powerfailnow, powerfail actions are set.


Unfortunately there doesn't seem be be any equivalent code in the
upstart init. grepping through the sources of upstart-0.3.5 I could
only find one instance of SIGPWR in /nih/signals.c, but there are no
handlers for SIGPWR in the upstart init that I could find. As far as I
can see upstart init ignores the SIGPWR interupt.

Maybe I'm missing something ... very possible.

Thanks,
Will





More information about the upstart-devel mailing list