diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ctl.c | 6 | ||||
-rw-r--r-- | src/pies.c | 7 | ||||
-rw-r--r-- | src/pies.h | 16 | ||||
-rw-r--r-- | src/prog.h | 2 | ||||
-rw-r--r-- | src/progman.c | 33 | ||||
-rw-r--r-- | src/sysvinit.c | 94 |
6 files changed, 132 insertions, 26 deletions
@@ -1826,7 +1826,9 @@ prog_serialize (struct json_value *ret, struct prog *prog) + if (prog->v.p.comp->runlevels) + json_object_set_string (ret, "runlevels", "%s", + prog->v.p.comp->runlevels); + if (prog->v.p.status == status_sleeping) - { json_object_set_number (ret, "wakeup-time", prog->v.p.timestamp + SLEEPTIME); - } @@ -2192,2 +2192,3 @@ main (int argc, char **argv) pies_reload (); + got_alarm = 1; action = ACTION_CONT; @@ -2218,2 +2219,8 @@ main (int argc, char **argv) break; + + case ACTION_POWER: + debug (1, ("SIGPWR")); + sysvinit_power (); + got_alarm = 1; + action = ACTION_CONT; } @@ -272,3 +272,4 @@ enum pies_action { ACTION_CTRLALTDEL, - ACTION_KBREQUEST + ACTION_KBREQUEST, + ACTION_POWER }; @@ -318,3 +319,3 @@ void free_action (struct action *act); void register_prog (struct component *comp); -int progman_running_p (void); +int progman_waiting_p (void); size_t progman_running_count (void); @@ -515,2 +516,3 @@ void sysvinit_runlevel_setup (int mask, int *wait); void sysvinit_sysdep_begin (void); +void sysvinit_power (void); @@ -523,2 +525,12 @@ extern char *init_fifo; +#ifndef POWER_STAT_FILE +# define POWER_STAT_FILE "/var/run/powerstatus" +#endif + +/* Power status values */ +#define POWER_STAT_FAIL 'F' +#define POWER_STAT_LOW 'L' +#define POWER_STAT_OK 'O' + +/* Request codes */ #define INIT_MAGIC 0x03091969 @@ -54,3 +54,3 @@ struct prog struct component *comp; - size_t idx; /* Numeric identifier */ + int wait; int socket; diff --git a/src/progman.c b/src/progman.c index 3bbd8b3..4ca3824 100644 --- a/src/progman.c +++ b/src/progman.c @@ -116,12 +116,2 @@ progman_lookup_tcpmux (const char *service, const char *master) -struct prog * -prog_lookup_by_idx (unsigned idx) -{ - struct prog *prog; - for (prog = proghead; prog; prog = prog->next) - if (IS_COMPONENT (prog) && prog->v.p.idx == idx) - break; - return prog; -} - void prog_stop (struct prog *prog, int sig); @@ -307,3 +297,3 @@ register_command (char *tag, char *command, pid_t pid) int -progman_running_p () +progman_waiting_p () { @@ -313,6 +303,10 @@ progman_running_p () { - if (IS_COMPONENT (prog) && is_comp_wait (prog->v.p.comp) && - prog->pid > 0) + if (IS_COMPONENT (prog) && prog->v.p.wait && prog->pid > 0) + { + debug(1, ("%s: waiting for %s (%lu)", + __FUNCTION__, prog_tag (prog), + (unsigned long) prog->pid)); return 1; } + } return 0; @@ -1061,2 +1055,3 @@ prog_start (struct prog *prog) } + prog->v.p.wait = is_comp_wait (prog->v.p.comp); debug (1, ("ok to start %s", prog->v.p.comp->tag)); @@ -1503,2 +1498,6 @@ progman_start () + if (progman_waiting_p ()) + /* Noting to do if there are processes left in the previous runlevel */ + return; + recompute_alarm = 0; @@ -1548,2 +1547,6 @@ progman_wake_sleeping (int onalrm) + if (progman_waiting_p ()) + /* Noting to do if there are processes left in the previous runlevel */ + return; + debug (1, (_("managing sleeping/stopping components"))); @@ -2256,2 +2259,5 @@ progman_cleanup (int expect_term) int status; + + if (!expect_term) + expect_term = progman_waiting_p (); while ((pid = waitpid (-1, &status, WNOHANG)) > 0) @@ -2306,2 +2312,3 @@ progman_cleanup (int expect_term) prog->v.p.status = status_finished; + prog->v.p.wait = 0; } 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); +} |