aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-02-28 20:42:50 +0200
committerSergey Poznyakoff <gray@gnu.org>2016-02-28 21:39:28 +0200
commit0d0a148121dcb8edd49cad900f27141336576f9d (patch)
treed458628bb80d5972f540826e1cf3fc8b8224265b /src
parent14e0802da5587179607f3340d105914435ee117a (diff)
downloadpies-0d0a148121dcb8edd49cad900f27141336576f9d.tar.gz
pies-0d0a148121dcb8edd49cad900f27141336576f9d.tar.bz2
Synchronize changes in runlevel with configuration reloads
State transition algorithm used this far could cause spurious component wakeups in some cases. Consider the following scenario: being in runlevel N, the configuration is changed so that a component X is added at runlevel N. Then a change to runlevel N+1 is initiated. What happens then is that X is woken up (still being in runlevel N) and terminated shortly afterwards, upon entering runlevel N+1. To avoid this, configuration must be reloaded after runlevel changes. * src/ctl.c (res_runlevel): Don't initiate ACTION_RELOAD after setting the runlevel. * src/pies.c (main): Begin main event loop with call to pies_pause. * src/pies.h (pies_set_hook): New proto. (inittrans): Remove proto. * src/socket.c (pies_set_hook): New function. (pies_pause): Call pies_pause_hook if defined. * src/sysvinit.c (inittrans): Change to static. If transition was initiated by user (e.g. by invoking telinit), schedule ACTION_RELOAD. (sysvinit_begin): Set inittrans as pies_hook
Diffstat (limited to 'src')
-rw-r--r--src/ctl.c1
-rw-r--r--src/pies.c4
-rw-r--r--src/pies.h2
-rw-r--r--src/socket.c11
-rw-r--r--src/sysvinit.c24
5 files changed, 30 insertions, 12 deletions
diff --git a/src/ctl.c b/src/ctl.c
index 731b31b..aca1d18 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -2149,7 +2149,6 @@ res_runlevel (struct ctlio *io, enum http_method meth,
2149 if (strlen (val->v.s) == 1 2149 if (strlen (val->v.s) == 1
2150 && sysvinit_set_runlevel (val->v.s[0]) == 0) 2150 && sysvinit_set_runlevel (val->v.s[0]) == 0)
2151 { 2151 {
2152 pies_schedule_action (ACTION_RELOAD);
2153 json_object_set_string (io->output.reply, "status", "OK"); 2152 json_object_set_string (io->output.reply, "status", "OK");
2154 } 2153 }
2155 else 2154 else
diff --git a/src/pies.c b/src/pies.c
index 6ea04d0..a678a7e 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -2220,9 +2220,7 @@ main (int argc, char **argv)
2220 2220
2221 do 2221 do
2222 { 2222 {
2223 if (init_process && inittrans ()) 2223 if (children_op == PIES_CHLD_NONE)
2224 action = ACTION_CONT;
2225 else if (children_op == PIES_CHLD_NONE)
2226 pies_pause (); 2224 pies_pause ();
2227 switch (action) 2225 switch (action)
2228 { 2226 {
diff --git a/src/pies.h b/src/pies.h
index 6fce820..4eb2aca 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -417,6 +417,7 @@ struct component *component_depmap_next (pies_depmap_pos_t pos);
417 417
418 418
419 419
420void pies_set_hook (int (*f) (void));
420void pies_pause (void); 421void pies_pause (void);
421 422
422enum 423enum
@@ -531,7 +532,6 @@ struct inetd_builtin *inetd_builtin_lookup (const char *service, int socktype);
531 532
532/* sysvinit.c */ 533/* sysvinit.c */
533void sysvinit_begin (void); 534void sysvinit_begin (void);
534int inittrans (void);
535int is_comp_wait (struct component *comp); 535int is_comp_wait (struct component *comp);
536int is_valid_runlevel (int c); 536int is_valid_runlevel (int c);
537int console_open (int mode); 537int console_open (int mode);
diff --git a/src/socket.c b/src/socket.c
index 2b2bc52..0a0a3a9 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -559,9 +559,20 @@ enable_socket (int fd)
559 FD_SET (fd, &fdset[PIES_EVT_EX]); 559 FD_SET (fd, &fdset[PIES_EVT_EX]);
560} 560}
561 561
562static int (*pies_pause_hook) (void);
563
564void
565pies_set_hook (int (*f) (void))
566{
567 pies_pause_hook = f;
568}
569
562void 570void
563pies_pause (void) 571pies_pause (void)
564{ 572{
573 if (pies_pause_hook && pies_pause_hook ())
574 return;
575
565 if (fd_max == -1) 576 if (fd_max == -1)
566 calc_fd_max (); 577 calc_fd_max ();
567 578
diff --git a/src/sysvinit.c b/src/sysvinit.c
index 46d62c3..f4ef101 100644
--- a/src/sysvinit.c
+++ b/src/sysvinit.c
@@ -63,6 +63,7 @@ int dfl_level;
63char *emergency_shell = "/sbin/sulogin"; 63char *emergency_shell = "/sbin/sulogin";
64int emergency; 64int emergency;
65 65
66static int inittrans (void);
66 67
67int 68int
68console_open (int mode) 69console_open (int mode)
@@ -532,10 +533,10 @@ sysvinit_fifo_handler (int fd, void *data)
532 { 533 {
533 case INIT_CMD_RUNLVL: 534 case INIT_CMD_RUNLVL:
534 buf.req.runlevel = toupper (buf.req.runlevel); 535 buf.req.runlevel = toupper (buf.req.runlevel);
535 pies_schedule_action (ACTION_RELOAD);
536 switch (buf.req.runlevel) 536 switch (buf.req.runlevel)
537 { 537 {
538 case 'Q': 538 case 'Q':
539 pies_schedule_action (ACTION_RELOAD);
539 break; 540 break;
540 541
541 default: 542 default:
@@ -799,6 +800,7 @@ sysvinit_begin (void)
799 add_extra_sigv (sigv, ARRAY_SIZE (sigv)); 800 add_extra_sigv (sigv, ARRAY_SIZE (sigv));
800 sysvinit_sysdep_begin (); 801 sysvinit_sysdep_begin ();
801 save_argv (); 802 save_argv ();
803 pies_set_hook (inittrans);
802 if (emergency) 804 if (emergency)
803 start_shell (emergency_shell); 805 start_shell (emergency_shell);
804} 806}
@@ -815,7 +817,8 @@ inittrans (void)
815 int newlevel = 0; 817 int newlevel = 0;
816 enum boot_state newstate; 818 enum boot_state newstate;
817 int trans = 0; 819 int trans = 0;
818 820 int userchg = 0;
821
819 if (progman_waiting_p ()) 822 if (progman_waiting_p ())
820 /* Noting to do if there are processes left in the previous runlevel */ 823 /* Noting to do if there are processes left in the previous runlevel */
821 return 0; 824 return 0;
@@ -855,6 +858,8 @@ inittrans (void)
855 ctl_open (); 858 ctl_open ();
856 diag_setup (DIAG_TO_SYSLOG | DIAG_REOPEN_LOG); 859 diag_setup (DIAG_TO_SYSLOG | DIAG_REOPEN_LOG);
857 } 860 }
861 else
862 userchg = 1;
858 } 863 }
859 if (newlevel && newlevel != runlevel) 864 if (newlevel && newlevel != runlevel)
860 { 865 {
@@ -870,8 +875,14 @@ inittrans (void)
870 if (trans) 875 if (trans)
871 { 876 {
872 envsetup (); 877 envsetup ();
873 sysvinit_runlevel_setup (PIES_COMP_DEFAULT); 878
874 pies_schedule_children (PIES_CHLD_WAKEUP); 879 if (userchg)
880 pies_schedule_action (ACTION_RELOAD);
881 else
882 {
883 sysvinit_runlevel_setup (PIES_COMP_DEFAULT);
884 pies_schedule_children (PIES_CHLD_WAKEUP);
885 }
875 } 886 }
876 return trans; 887 return trans;
877} 888}
@@ -1254,8 +1265,7 @@ sysvinit_report (struct json_value *obj)
1254 json_object_set_string (obj, "bootstate", "%s", 1265 json_object_set_string (obj, "bootstate", "%s",
1255 boot_state_name[boot_state]); 1266 boot_state_name[boot_state]);
1256 if (initdefault) 1267 if (initdefault)
1257 json_object_set_string (obj, "initdefault", "%c", 1268 json_object_set_string (obj, "initdefault", "%c", initdefault);
1258 initdefault);
1259} 1269}
1260 1270
1261void 1271void

Return to:

Send suggestions and report system problems to the System administrator.