summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org>2016-01-31 11:43:18 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2016-01-31 11:43:18 (GMT)
commit6f9f2fd7a6952b544dccbf0bdc7f9c312f602afe (patch) (unidiff)
tree8bf0b45bb6578dee844dc92c1a90a93474f0fa7a
parent7f20aa4f7e26d8f740b55bef98f0c3c78eca0e79 (diff)
downloadpies-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 (more/less context) (ignore whitespace changes)
-rw-r--r--src/ctl.c10
-rw-r--r--src/pies.c7
-rw-r--r--src/pies.h16
-rw-r--r--src/prog.h2
-rw-r--r--src/progman.c35
-rw-r--r--src/sysvinit.c94
6 files changed, 135 insertions, 29 deletions
diff --git a/src/ctl.c b/src/ctl.c
index d3e6b64..0e5ea97 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -1826,7 +1826,9 @@ prog_serialize (struct json_value *ret, struct prog *prog)
1826 1826
1827 if (prog->v.p.comp->runlevels)
1828 json_object_set_string (ret, "runlevels", "%s",
1829 prog->v.p.comp->runlevels);
1830
1827 if (prog->v.p.status == status_sleeping) 1831 if (prog->v.p.status == status_sleeping)
1828 { 1832 json_object_set_number (ret, "wakeup-time",
1829 json_object_set_number (ret, "wakeup-time", 1833 prog->v.p.timestamp + SLEEPTIME);
1830 prog->v.p.timestamp + SLEEPTIME);
1831 }
1832 1834
diff --git a/src/pies.c b/src/pies.c
index 1bce1eb..96e9281 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -2192,2 +2192,3 @@ main (int argc, char **argv)
2192 pies_reload (); 2192 pies_reload ();
2193 got_alarm = 1;
2193 action = ACTION_CONT; 2194 action = ACTION_CONT;
@@ -2218,2 +2219,8 @@ main (int argc, char **argv)
2218 break; 2219 break;
2220
2221 case ACTION_POWER:
2222 debug (1, ("SIGPWR"));
2223 sysvinit_power ();
2224 got_alarm = 1;
2225 action = ACTION_CONT;
2219 } 2226 }
diff --git a/src/pies.h b/src/pies.h
index ad8e8ee..39977c7 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -272,3 +272,4 @@ enum pies_action {
272 ACTION_CTRLALTDEL, 272 ACTION_CTRLALTDEL,
273 ACTION_KBREQUEST 273 ACTION_KBREQUEST,
274 ACTION_POWER
274}; 275};
@@ -318,3 +319,3 @@ void free_action (struct action *act);
318void register_prog (struct component *comp); 319void register_prog (struct component *comp);
319int progman_running_p (void); 320int progman_waiting_p (void);
320size_t progman_running_count (void); 321size_t progman_running_count (void);
@@ -515,2 +516,3 @@ void sysvinit_runlevel_setup (int mask, int *wait);
515void sysvinit_sysdep_begin (void); 516void sysvinit_sysdep_begin (void);
517void sysvinit_power (void);
516 518
@@ -523,2 +525,12 @@ extern char *init_fifo;
523 525
526#ifndef POWER_STAT_FILE
527# define POWER_STAT_FILE "/var/run/powerstatus"
528#endif
529
530/* Power status values */
531#define POWER_STAT_FAIL 'F'
532#define POWER_STAT_LOW 'L'
533#define POWER_STAT_OK 'O'
534
535/* Request codes */
524#define INIT_MAGIC 0x03091969 536#define INIT_MAGIC 0x03091969
diff --git a/src/prog.h b/src/prog.h
index a29de04..fe42d3a 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -54,3 +54,3 @@ struct prog
54 struct component *comp; 54 struct component *comp;
55 size_t idx; /* Numeric identifier */ 55 int wait;
56 int socket; 56 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)
116 116
117struct prog *
118prog_lookup_by_idx (unsigned idx)
119{
120 struct prog *prog;
121 for (prog = proghead; prog; prog = prog->next)
122 if (IS_COMPONENT (prog) && prog->v.p.idx == idx)
123 break;
124 return prog;
125}
126
127void prog_stop (struct prog *prog, int sig); 117void prog_stop (struct prog *prog, int sig);
@@ -307,3 +297,3 @@ register_command (char *tag, char *command, pid_t pid)
307int 297int
308progman_running_p () 298progman_waiting_p ()
309{ 299{
@@ -313,5 +303,9 @@ progman_running_p ()
313 { 303 {
314 if (IS_COMPONENT (prog) && is_comp_wait (prog->v.p.comp) && 304 if (IS_COMPONENT (prog) && prog->v.p.wait && prog->pid > 0)
315 prog->pid > 0) 305 {
316 return 1; 306 debug(1, ("%s: waiting for %s (%lu)",
307 __FUNCTION__, prog_tag (prog),
308 (unsigned long) prog->pid));
309 return 1;
310 }
317 } 311 }
@@ -1061,2 +1055,3 @@ prog_start (struct prog *prog)
1061 } 1055 }
1056 prog->v.p.wait = is_comp_wait (prog->v.p.comp);
1062 debug (1, ("ok to start %s", prog->v.p.comp->tag)); 1057 debug (1, ("ok to start %s", prog->v.p.comp->tag));
@@ -1503,2 +1498,6 @@ progman_start ()
1503 1498
1499 if (progman_waiting_p ())
1500 /* Noting to do if there are processes left in the previous runlevel */
1501 return;
1502
1504 recompute_alarm = 0; 1503 recompute_alarm = 0;
@@ -1548,2 +1547,6 @@ progman_wake_sleeping (int onalrm)
1548 1547
1548 if (progman_waiting_p ())
1549 /* Noting to do if there are processes left in the previous runlevel */
1550 return;
1551
1549 debug (1, (_("managing sleeping/stopping components"))); 1552 debug (1, (_("managing sleeping/stopping components")));
@@ -2256,2 +2259,5 @@ progman_cleanup (int expect_term)
2256 int status; 2259 int status;
2260
2261 if (!expect_term)
2262 expect_term = progman_waiting_p ();
2257 while ((pid = waitpid (-1, &status, WNOHANG)) > 0) 2263 while ((pid = waitpid (-1, &status, WNOHANG)) > 0)
@@ -2306,2 +2312,3 @@ progman_cleanup (int expect_term)
2306 prog->v.p.status = status_finished; 2312 prog->v.p.status = status_finished;
2313 prog->v.p.wait = 0;
2307 } 2314 }
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)
404char *init_fifo = INIT_FIFO; 404char *init_fifo = INIT_FIFO;
405
405static void create_fifo (void); 406static void create_fifo (void);
407static void powerfailcmd (int power_stat);
406 408
@@ -458,3 +460,2 @@ sysvinit_fifo_handler (int fd, void *data)
458 { 460 {
459 progman_stop ();
460 dfl_level = buf.req.runlevel; 461 dfl_level = buf.req.runlevel;
@@ -469,2 +470,14 @@ sysvinit_fifo_handler (int fd, void *data)
469 470
471 case INIT_CMD_POWERFAIL:
472 powerfailcmd (POWER_STAT_FAIL);
473 break;
474
475 case INIT_CMD_POWERFAILNOW:
476 powerfailcmd (POWER_STAT_LOW);
477 break;
478
479 case INIT_CMD_POWEROK:
480 powerfailcmd (POWER_STAT_OK);
481 break;
482
470 /* FIXME: react on other commands */ 483 /* FIXME: react on other commands */
@@ -575,2 +588,5 @@ sysvinit_sigtrans (int sig, int *pact)
575 break; 588 break;
589 case SIGPWR:
590 *pact = ACTION_POWER;
591 break;
576 default: 592 default:
@@ -656,3 +672,3 @@ inittrans ()
656 672
657 if (progman_running_p ()) 673 if (progman_waiting_p ())
658 /* Noting to do if there are processes left in the previous runlevel */ 674 /* Noting to do if there are processes left in the previous runlevel */
@@ -728,8 +744,10 @@ is_comp_wait (struct component *comp)
728 { 744 {
729 case pies_comp_boot: 745 case pies_comp_sysinit:
730 case pies_comp_powerfail: 746 case pies_comp_bootwait:
731 case pies_comp_ctrlaltdel: 747 case pies_comp_wait:
748 case pies_comp_powerwait:
732 case pies_comp_powerfailnow: 749 case pies_comp_powerfailnow:
733 case pies_comp_kbrequest: 750 case pies_comp_powerokwait:
734 return 0; 751 case pies_comp_ctrlaltdel:
752 return 1;
735 default: 753 default:
@@ -737,3 +755,3 @@ is_comp_wait (struct component *comp)
737 } 755 }
738 return 1; 756 return 0;
739} 757}
@@ -973 +991,61 @@ inittab_parse (const char *file)
973} 991}
992
993char *power_stat_file = POWER_STAT_FILE;
994
995void
996sysvinit_power (void)
997{
998 int power_stat = POWER_STAT_FAIL;
999 int fd;
1000
1001 fd = open (power_stat_file, O_RDONLY);
1002 if (fd >= 0)
1003 {
1004 char c;
1005 switch (read (fd, &c, 1))
1006 {
1007 case 1:
1008 power_stat = c;
1009 break;
1010
1011 case 0:
1012 logmsg (LOG_NOTICE, _("unexpected EOF on %s"), power_stat_file);
1013 break;
1014
1015 case -1:
1016 logmsg (LOG_ERR, _("error reading from %s: %s"),
1017 power_stat_file, strerror (errno));
1018 }
1019 close (fd);
1020 if (unlink (power_stat_file))
1021 logmsg (LOG_ERR, _("can't unlink %s: %s"), power_stat_file,
1022 strerror (errno));
1023 }
1024 else
1025 debug (1, (_("can't open %s: %s"), power_stat_file, strerror (errno)));
1026
1027 powerfailcmd (power_stat);
1028}
1029
1030static void
1031powerfailcmd (int power_stat)
1032{
1033 int mask;
1034
1035 switch (power_stat)
1036 {
1037 case POWER_STAT_OK: /* The power is OK */
1038 mask = PIES_COMP_MASK (pies_comp_powerokwait);
1039 break;
1040
1041 case POWER_STAT_LOW: /* Low battery: shut down now */
1042 mask = PIES_COMP_MASK (pies_comp_powerfailnow);
1043 break;
1044
1045 default: /* Power failure */
1046 mask = PIES_COMP_MASK (pies_comp_powerfail)
1047 | PIES_COMP_MASK (pies_comp_powerwait);
1048 }
1049
1050 sysvinit_runlevel_setup (mask, NULL);
1051}

Return to:

Send suggestions and report system problems to the System administrator.