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