diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-01-31 13:43:18 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-01-31 13:43:18 +0200 |
commit | 6f9f2fd7a6952b544dccbf0bdc7f9c312f602afe (patch) | |
tree | 8bf0b45bb6578dee844dc92c1a90a93474f0fa7a /src/sysvinit.c | |
parent | 7f20aa4f7e26d8f740b55bef98f0c3c78eca0e79 (diff) | |
download | pies-6f9f2fd7a6952b544dccbf0bdc7f9c312f602afe.tar.gz pies-6f9f2fd7a6952b544dccbf0bdc7f9c312f602afe.tar.bz2 |
Fix runlevel switching; handle powerfail commands.
* src/ctl.c (prog_serialize): List runlevels.
* src/pies.c (main): Set got_alarm after reloading configuration.
Handle ACTION_POWER.
* src/pies.h (ACTION_POWER): New constant.
(progman_running_p): Rename to progman_waiting_p. All uses changed.
(sysvinit_power): New proto.
(POWER_STAT_FILE): New define.
(POWER_STAT_FAIL,POWER_STAT_LOW,POWER_STAT_OK): New constants.
* src/prog.h (prog) <idx>: Remove.
(prog) <wait>: New member.
* src/progman.c (prog_lookup_by_idx): Remove.
(progman_waiting_p): Return 1 only if there is at least one
prog with v.p.wait set.
(prog_start): Initialize v.p.wait for sysvinit components.
(progman_start): Don't do anything if waiting for components from
the previous runlevel.
(progman_wake_sleeping): Likewise.
(progman_cleanup): Assume expect_term if waiting for components from
the previous runlevel.
Clear v.p.wait on exited progs.
* src/sysvinit.c (sysvinit_fifo_handler): Don't call progman_stop
when handling runlevel changes.
Handle INIT_CMD_POWERFAIL, INIT_CMD_POWERFAILNOW, and
INIT_CMD_POWEROK.
(sysvinit_sigtrans): Handle SIGPWR.
(is_comp_wait): Rewrite.
(power_stat_file): New variable.
(sysvinit_power): New function.
Diffstat (limited to 'src/sysvinit.c')
-rw-r--r-- | src/sysvinit.c | 94 |
1 files changed, 86 insertions, 8 deletions
diff --git a/src/sysvinit.c b/src/sysvinit.c index d8b7cc5..be7aef8 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -404,3 +404,5 @@ sysvinit_setenv (char const *data, int size) char *init_fifo = INIT_FIFO; + static void create_fifo (void); +static void powerfailcmd (int power_stat); @@ -458,3 +460,2 @@ sysvinit_fifo_handler (int fd, void *data) { - progman_stop (); dfl_level = buf.req.runlevel; @@ -469,2 +470,14 @@ sysvinit_fifo_handler (int fd, void *data) + case INIT_CMD_POWERFAIL: + powerfailcmd (POWER_STAT_FAIL); + break; + + case INIT_CMD_POWERFAILNOW: + powerfailcmd (POWER_STAT_LOW); + break; + + case INIT_CMD_POWEROK: + powerfailcmd (POWER_STAT_OK); + break; + /* FIXME: react on other commands */ @@ -575,2 +588,5 @@ sysvinit_sigtrans (int sig, int *pact) break; + case SIGPWR: + *pact = ACTION_POWER; + break; default: @@ -656,3 +672,3 @@ inittrans () - if (progman_running_p ()) + if (progman_waiting_p ()) /* Noting to do if there are processes left in the previous runlevel */ @@ -728,8 +744,10 @@ is_comp_wait (struct component *comp) { - case pies_comp_boot: - case pies_comp_powerfail: - case pies_comp_ctrlaltdel: + case pies_comp_sysinit: + case pies_comp_bootwait: + case pies_comp_wait: + case pies_comp_powerwait: case pies_comp_powerfailnow: - case pies_comp_kbrequest: - return 0; + case pies_comp_powerokwait: + case pies_comp_ctrlaltdel: + return 1; default: @@ -737,3 +755,3 @@ is_comp_wait (struct component *comp) } - return 1; + return 0; } @@ -973 +991,61 @@ inittab_parse (const char *file) } + +char *power_stat_file = POWER_STAT_FILE; + +void +sysvinit_power (void) +{ + int power_stat = POWER_STAT_FAIL; + int fd; + + fd = open (power_stat_file, O_RDONLY); + if (fd >= 0) + { + char c; + switch (read (fd, &c, 1)) + { + case 1: + power_stat = c; + break; + + case 0: + logmsg (LOG_NOTICE, _("unexpected EOF on %s"), power_stat_file); + break; + + case -1: + logmsg (LOG_ERR, _("error reading from %s: %s"), + power_stat_file, strerror (errno)); + } + close (fd); + if (unlink (power_stat_file)) + logmsg (LOG_ERR, _("can't unlink %s: %s"), power_stat_file, + strerror (errno)); + } + else + debug (1, (_("can't open %s: %s"), power_stat_file, strerror (errno))); + + powerfailcmd (power_stat); +} + +static void +powerfailcmd (int power_stat) +{ + int mask; + + switch (power_stat) + { + case POWER_STAT_OK: /* The power is OK */ + mask = PIES_COMP_MASK (pies_comp_powerokwait); + break; + + case POWER_STAT_LOW: /* Low battery: shut down now */ + mask = PIES_COMP_MASK (pies_comp_powerfailnow); + break; + + default: /* Power failure */ + mask = PIES_COMP_MASK (pies_comp_powerfail) + | PIES_COMP_MASK (pies_comp_powerwait); + } + + sysvinit_runlevel_setup (mask, NULL); +} |