aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-05-24 12:45:25 +0300
committerSergey Poznyakoff <gray@gnu.org>2019-05-24 13:50:39 +0300
commit6dd0ec08db301984b8f8f9082f28006d5915c183 (patch)
treee916ad37fbd3cbcaf85103667f28e0d47f3c2e45
parent2a646ee7cbbcb6f4bbd8f38bb3c1e1418550f3fc (diff)
downloadpies-6dd0ec08db301984b8f8f9082f28006d5915c183.tar.gz
pies-6dd0ec08db301984b8f8f9082f28006d5915c183.tar.bz2
Initial implementation of "startup" components.
These are components that are run at program startup. Starting other components is delayed until all startup components terminate. This is similar to SysV "bootwait" components. Upon termination, startup components are removed from the configuration. They are not renewed upon configuratuion reload. * src/comp.c (comp_array_remove): Remove from the depmap as well. (component_ref_decr): Use comp_array_remove for active components and plain component_free for inactive ones. (component_build_depmap): Use comp_array_remove. (component_config_commit): Special handling for pies_comp_startup components. * src/pies.c (modetab): New component modes: "startup" and "shutdown". (main): Run program_init_startup. * src/pies.h (pies_comp_mode): New modes: pies_comp_startup and pies_comp_shutdown. (program_init_startup): New proto. * src/progman.c (progman_waiting_p): Return 1 if a startup component is still running. (program_init_startup): New function. (progman_cleanup): Handle pies_comp_startup termination. * src/socket.c (switch_eids): Avoid unnecessary calls to setegid and seteuid. * tests/atlocal.in (auxdir): New variable. * tests/mailer: Move to tests/aux/ * tests/respawn: Move to tests/aux/ * tests/retcode: Move to tests/aux/ * tests/aux/startup: New auxiliary program. * tests/redirect.at: Start components from $auxdir. * tests/respawn.at: Likewise. * tests/ret-exec.at: Likewise. * tests/ret-notify.at: Likewise. * tests/startup.at: New file. * tests/testsuite.at: Include startup.at * tests/Makefile.am: Add new tests.
-rw-r--r--src/comp.c87
-rw-r--r--src/pies.c115
-rw-r--r--src/pies.h38
-rw-r--r--src/progman.c291
-rw-r--r--src/socket.c54
-rw-r--r--tests/Makefile.am9
-rw-r--r--tests/atlocal.in2
-rwxr-xr-xtests/aux/mailer (renamed from tests/mailer)0
-rwxr-xr-xtests/aux/respawn (renamed from tests/respawn)0
-rwxr-xr-xtests/aux/retcode (renamed from tests/retcode)0
-rwxr-xr-xtests/aux/startup7
-rw-r--r--tests/redirect.at2
-rw-r--r--tests/respawn.at2
-rw-r--r--tests/ret-exec.at4
-rw-r--r--tests/ret-notify.at6
-rw-r--r--tests/startup.at84
-rw-r--r--tests/testsuite.at1
17 files changed, 442 insertions, 260 deletions
diff --git a/src/comp.c b/src/comp.c
index c3e998a..2346306 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -24,6 +24,11 @@ struct complist
24 struct component *tail; 24 struct component *tail;
25}; 25};
26 26
27/* 0 on the first load, and 1 on all subsequent reloads. Tells the
28 component_config_commit whether we're starting from scratch or just
29 updating an already loaded configuration */
30static int loaded;
31
27static struct complist comp_list[2]; 32static struct complist comp_list[2];
28static int cur; 33static int cur;
29 34
@@ -32,13 +37,13 @@ static size_t comp_count;
32 37
33static pies_depmap_t depmap; 38static pies_depmap_t depmap;
34 39
35static int 40static inline int
36next_index (void) 41next_index (void)
37{ 42{
38 return (cur + 1) % ARRAY_SIZE (comp_list); 43 return (cur + 1) % ARRAY_SIZE (comp_list);
39} 44}
40 45
41static int 46static inline int
42prev_index (void) 47prev_index (void)
43{ 48{
44 return (cur + ARRAY_SIZE (comp_list) - 1) % ARRAY_SIZE (comp_list); 49 return (cur + ARRAY_SIZE (comp_list) - 1) % ARRAY_SIZE (comp_list);
@@ -85,6 +90,22 @@ component_append (struct component *comp)
85} 90}
86 91
87void 92void
93comp_array_remove (size_t i)
94{
95 struct component *comp = comp_array[i];
96
97 depmap_remove (depmap, i);
98 while (i < comp_count -1)
99 {
100 comp_array[i] = comp_array[i+1];
101 comp_array[i]->arridx = i;
102 i++;
103 }
104 component_free (comp);
105 comp_count--;
106}
107
108void
88component_unlink (struct component *comp) 109component_unlink (struct component *comp)
89{ 110{
90 struct complist *list = &comp_list[comp->listidx]; 111 struct complist *list = &comp_list[comp->listidx];
@@ -201,7 +222,12 @@ component_ref_decr (struct component *comp)
201{ 222{
202 assert (comp->ref_count > 0); 223 assert (comp->ref_count > 0);
203 if (--comp->ref_count == 0) 224 if (--comp->ref_count == 0)
204 component_free (comp); 225 {
226 if (component_is_active (comp))
227 comp_array_remove (comp->arridx);
228 else
229 component_free (comp);
230 }
205} 231}
206 232
207static int 233static int
@@ -425,17 +451,6 @@ report_cyclic_dependency (pies_depmap_t dp, size_t idx)
425} 451}
426 452
427void 453void
428comp_array_remove (size_t i)
429{
430 struct component *comp = comp_array[i];
431 if (i < comp_count - 1)
432 memmove (&comp_array[i], &comp_array[i+1],
433 (comp_count - i - 1) * sizeof comp_array[0]);
434 component_free (comp);
435 comp_count--;
436}
437
438void
439component_build_depmap (void) 454component_build_depmap (void)
440{ 455{
441 size_t i; 456 size_t i;
@@ -460,7 +475,6 @@ component_build_depmap (void)
460 "which is not declared"), 475 "which is not declared"),
461 comp->tag, tag); 476 comp->tag, tag);
462 comp_array_remove (i); 477 comp_array_remove (i);
463 depmap_remove (depmap, i);
464 continue; 478 continue;
465 } 479 }
466 depmap_set (depmap, i, tgt); 480 depmap_set (depmap, i, tgt);
@@ -497,10 +511,7 @@ component_build_depmap (void)
497 511
498 for (i = 0; i < comp_count;) 512 for (i = 0; i < comp_count;)
499 if (comp_array[i]->flags & CF_REMOVE) 513 if (comp_array[i]->flags & CF_REMOVE)
500 { 514 comp_array_remove (i);
501 comp_array_remove (i);
502 depmap_remove (depmap, i);
503 }
504 else 515 else
505 i++; 516 i++;
506 517
@@ -528,22 +539,36 @@ component_config_commit (void)
528 comp_array = grecs_realloc (comp_array, i * sizeof (comp_array[0])); 539 comp_array = grecs_realloc (comp_array, i * sizeof (comp_array[0]));
529 comp_count = i; 540 comp_count = i;
530 541
531 /* Rearrange components, registering prog entries for the new ones */ 542 /* Rearrange components, registering entries for the new ones */
532 for (comp = list->head, i = 0; comp; comp = comp->next, i++) 543 for (comp = list->head, i = 0; comp; )
533 { 544 {
534 match = complist_find_match (prev, comp); 545 struct component *next = comp->next;
535 if (match) 546 if (loaded && comp->mode == pies_comp_startup)
536 { 547 {
537 component_merge (match, comp); 548 /* Ignore startup components */
538 component_unlink (match); 549 component_unlink (comp);
539 match->listidx = cur;
540 component_link (match, comp->prev);
541 component_free (comp); 550 component_free (comp);
542 comp = match;
543 } 551 }
544 comp_array[i] = comp; 552 else
545 comp->arridx = i; 553 {
554 match = complist_find_match (prev, comp);
555 if (match)
556 {
557 component_merge (match, comp);
558 component_unlink (match);
559 match->listidx = cur;
560 component_link (match, comp->prev);
561 component_free (comp);
562 comp = match;
563 }
564 comp_array[i] = comp;
565 comp->arridx = i;
566 i++;
567 }
568 comp = next;
546 } 569 }
570 /* Adjust comp_count */
571 comp_count = i;
547 572
548 /* Mark orphaned progs for termination */ 573 /* Mark orphaned progs for termination */
549 list = &comp_list[prev]; 574 list = &comp_list[prev];
@@ -560,6 +585,8 @@ component_config_commit (void)
560 for (comp = comp_list[cur].head; comp; comp = comp->next) 585 for (comp = comp_list[cur].head; comp; comp = comp->next)
561 if (!comp->prog) 586 if (!comp->prog)
562 register_prog (comp); 587 register_prog (comp);
588
589 loaded = 1;
563} 590}
564 591
565static int 592static int
diff --git a/src/pies.c b/src/pies.c
index 89c0b7e..98488a6 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -132,7 +132,7 @@ int
132config_file_remove (const char *name) 132config_file_remove (const char *name)
133{ 133{
134 struct grecs_list_entry *ep; 134 struct grecs_list_entry *ep;
135 135
136 for (ep = config_list->head; ep; ep = ep->next) 136 for (ep = config_list->head; ep; ep = ep->next)
137 { 137 {
138 struct config_file *file = ep->data; 138 struct config_file *file = ep->data;
@@ -156,7 +156,7 @@ void
156config_file_list_serialize (struct json_value *ar) 156config_file_list_serialize (struct json_value *ar)
157{ 157{
158 struct grecs_list_entry *ep; 158 struct grecs_list_entry *ep;
159 159
160 for (ep = config_list->head; ep; ep = ep->next) 160 for (ep = config_list->head; ep; ep = ep->next)
161 { 161 {
162 struct config_file *file = ep->data; 162 struct config_file *file = ep->data;
@@ -327,7 +327,7 @@ action_free (struct action *act)
327 free (act->addr); 327 free (act->addr);
328 free (act->message); 328 free (act->message);
329 free (act->command); 329 free (act->command);
330 330
331 free (act); 331 free (act);
332} 332}
333 333
@@ -359,7 +359,7 @@ create_action (struct component *comp,
359 unsigned n; 359