aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-02-19 08:41:12 +0200
committerSergey Poznyakoff <gray@gnu.org>2016-02-19 08:41:12 +0200
commite6902abfddb4d7b16dc9a4231a3781f354a08cd5 (patch)
treec634621af2ae765460e010ce83c8492ed4e859bc /src
parent51a797445a4bfc34ad1ae7ea91e12486d823abda (diff)
downloadpies-e6902abfddb4d7b16dc9a4231a3781f354a08cd5.tar.gz
pies-e6902abfddb4d7b16dc9a4231a3781f354a08cd5.tar.bz2
Revamp program termination after reconfiguring.
* src/pies.h (PIES_CHLD_GC): New op. (progman_stop_tag): Remove proto. * src/pies.c (main): Handle PIES_CHLD_GC: stop all programs marked for termination. * src/comp.c (component_config_commit): Mark leftover components for termination, instead of waiting for them to terminate. * src/sysvinit.c (runlevel_setup_prog): Skip prog if its active status didn't change. Mark inactivated progs for termination. (sysvinit_runlevel_setup): Schedule PIES_CHLD_GC. (inittrans): Don't wait for programs to terminate. That will be done in the main loop. * src/prog.h (prog)<stop>: New boolean member. * src/progman.c (progman_cleanup) (progman_stop_component): Clear the stop flag. (progman_gc): New function. (progman_stop_tag): Remove.
Diffstat (limited to 'src')
-rw-r--r--src/comp.c32
-rw-r--r--src/pies.c2
-rw-r--r--src/pies.h2
-rw-r--r--src/prog.h5
-rw-r--r--src/progman.c95
-rw-r--r--src/sysvinit.c42
6 files changed, 102 insertions, 76 deletions
diff --git a/src/comp.c b/src/comp.c
index 6a0e4ba..b340abe 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -358,31 +358,15 @@ prog_is_leftover (struct prog *prog)
358 return IS_COMPONENT (prog) && !component_is_active (prog->v.p.comp); 358 return IS_COMPONENT (prog) && !component_is_active (prog->v.p.comp);
359} 359}
360 360
361/* If PROG is a leftover, gracefully stop it and mark as disabled */ 361/* If PROG is a leftover, mark it for termination */
362static int 362static int
363cb_terminate_prog (struct prog *prog, void *data) 363mark_prog (struct prog *prog, void *data)
364{ 364{
365 if (prog_is_leftover (prog)) 365 if (prog_is_leftover (prog))
366 progman_stop_component (&prog); 366 prog->v.p.stop = 1;
367 return 0; 367 return 0;
368} 368}
369 369
370/* If PROG is a leftover, slay it with SIGKILL */
371static int
372cb_kill_prog (struct prog *prog, void *data)
373{
374 if (prog_is_leftover (prog))
375 prog_stop (prog, SIGKILL);
376 return 0;
377}
378
379static int
380list_is_empty (void *p)
381{
382 struct complist *list = p;
383 return list->head == NULL;
384}
385
386static int 370static int
387list_str_cmp (const void *a, const void *b) 371list_str_cmp (const void *a, const void *b)
388{ 372{
@@ -504,16 +488,12 @@ component_config_commit (void)
504 comp->arridx = i; 488 comp->arridx = i;
505 } 489 }
506 490
507 /* Terminate orphaned progs */ 491 /* Mark orphaned progs for termination */
508 list = &comp_list[prev]; 492 list = &comp_list[prev];
509 if (list->head) 493 if (list->head)
510 { 494 {
511 progman_foreach (cb_terminate_prog, NULL); 495 progman_foreach (mark_prog, NULL);
512 if (progman_wait_until (list_is_empty, list)) 496 pies_schedule_children (PIES_CHLD_GC);
513 {
514 progman_foreach (cb_kill_prog, NULL);
515 progman_wait_until (list_is_empty, list);
516 }
517 } 497 }
518 498
519 /* Build dependency map */ 499 /* Build dependency map */
diff --git a/src/pies.c b/src/pies.c
index 046f681..cb4d2f5 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -2221,6 +2221,8 @@ main (int argc, char **argv)
2221 } 2221 }
2222 if (action == ACTION_CONT) 2222 if (action == ACTION_CONT)
2223 { 2223 {
2224 if (children_op & PIES_CHLD_GC)
2225 progman_gc ();
2224 if (children_op & PIES_CHLD_CLEANUP) 2226 if (children_op & PIES_CHLD_CLEANUP)
2225 progman_cleanup (0); 2227 progman_cleanup (0);
2226 if (children_op & PIES_CHLD_WAKEUP) 2228 if (children_op & PIES_CHLD_WAKEUP)
diff --git a/src/pies.h b/src/pies.h
index 9a3dfca..b61e11b 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -318,6 +318,7 @@ void free_action (struct action *act);
318#define PIES_CHLD_NONE 0 318#define PIES_CHLD_NONE 0
319#define PIES_CHLD_CLEANUP 0x01 319#define PIES_CHLD_CLEANUP 0x01
320#define PIES_CHLD_WAKEUP 0x02 320#define PIES_CHLD_WAKEUP 0x02
321#define PIES_CHLD_GC 0x04
321 322
322void pies_schedule_children (int op); 323void pies_schedule_children (int op);
323 324
@@ -330,7 +331,6 @@ void progman_cleanup (int expect_term);
330void progman_filter (int (*filter) (struct component *, void *data), 331void progman_filter (int (*filter) (struct component *, void *data),
331 void *data); 332 void *data);
332int progman_wait_until (int (*cond) (void *), void *data); 333int progman_wait_until (int (*cond) (void *), void *data);
333void progman_stop_tag (const char *name);
334int progman_accept (int socket, void *data); 334int progman_accept (int socket, void *data);
335 335
336void progman_create_sockets (void); 336void progman_create_sockets (void);
diff --git a/src/prog.h b/src/prog.h
index 316a229..4e86596 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -51,8 +51,9 @@ struct prog
51 struct 51 struct
52 { 52 {
53 struct component *comp; 53 struct component *comp;
54 int wait :1; 54 int active :1; /* The prog is active */
55 int active :1; 55 int wait :1; /* Wait for this prog to terminate */
56 int stop :1; /* Stop this prog */
56 int socket; 57 int socket;
57 struct prog *redir[2]; /* Pointers to redirectors */ 58 struct prog *redir[2]; /* Pointers to redirectors */
58 time_t timestamp; /* Time of last startup */ 59 time_t timestamp; /* Time of last startup */
diff --git a/src/progman.c b/src/progman.c
index da5a970..52c875f 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -952,7 +952,6 @@ check_connection_rate (struct prog *prog)
952 return 0; 952 return 0;
953} 953}
954 954
955
956static int 955static int
957prog_open_socket (struct prog *prog) 956prog_open_socket (struct prog *prog)
958{ 957{
@@ -1473,7 +1472,6 @@ progman_create_sockets ()
1473 progman_foreach (prog_create_socket, NULL); 1472 progman_foreach (prog_create_socket, NULL);
1474} 1473}
1475 1474
1476
1477void 1475void
1478progman_recompute_alarm () 1476progman_recompute_alarm ()
1479{ 1477{
@@ -1508,9 +1506,7 @@ progman_recompute_alarm ()
1508 if (alarm_time) 1506 if (alarm_time)
1509 alarm (alarm_time); 1507 alarm (alarm_time);
1510} 1508}
1511
1512 1509
1513
1514void 1510void
1515progman_start () 1511progman_start ()
1516{ 1512{
@@ -2315,6 +2311,7 @@ progman_cleanup (int expect_term)
2315 { 2311 {
2316 case TYPE_COMPONENT: 2312 case TYPE_COMPONENT:
2317 print_status (prog_tag (prog), pid, status, expect_term); 2313 print_status (prog_tag (prog), pid, status, expect_term);
2314 prog->v.p.stop = 0;
2318 if (prog->v.p.comp->mode == pies_comp_inetd) 2315 if (prog->v.p.comp->mode == pies_comp_inetd)
2319 { 2316 {
2320 struct prog *listener = prog->v.p.listener; 2317 struct prog *listener = prog->v.p.listener;
@@ -2418,6 +2415,7 @@ progman_stop_component (struct prog **progptr)
2418 prog_deactivate_listener (prog); 2415 prog_deactivate_listener (prog);
2419 /* fall through */ 2416 /* fall through */
2420 case status_stopped: 2417 case status_stopped:
2418 prog->v.p.stop = 0;
2421 if (!component_is_active (prog->v.p.comp)) 2419 if (!component_is_active (prog->v.p.comp))
2422 destroy_prog (progptr); 2420 destroy_prog (progptr);
2423 break; 2421 break;
@@ -2425,14 +2423,20 @@ progman_stop_component (struct prog **progptr)
2425 case status_sleeping: 2423 case status_sleeping:
2426 if (!component_is_active (prog->v.p.comp)) 2424 if (!component_is_active (prog->v.p.comp))
2427 destroy_prog (progptr); 2425 destroy_prog (progptr);
2426 else if (prog->v.p.stop)
2427 prog->v.p.stop = 0;
2428 else 2428 else
2429 { 2429 {
2430 logmsg (LOG_INFO, _("waking up component `%s'"), prog_tag (prog)); 2430 logmsg (LOG_INFO, _("waking up component `%s'"), prog_tag (prog));
2431 prog->v.p.failcount = 0; 2431 prog->v.p.failcount = 0;
2432 } 2432 }
2433 break; 2433 break;
2434
2435 case status_stopping:
2436 break;
2434 2437
2435 default: 2438 case status_finished:
2439 prog->v.p.stop = 0;
2436 if (!component_is_active (prog->v.p.comp)) 2440 if (!component_is_active (prog->v.p.comp))
2437 destroy_prog (progptr); 2441 destroy_prog (progptr);
2438 else 2442 else
@@ -2442,7 +2446,7 @@ progman_stop_component (struct prog **progptr)
2442 } 2446 }
2443 } 2447 }
2444} 2448}
2445 2449
2446void 2450void
2447prog_deactivate_listener (struct prog *prog) 2451prog_deactivate_listener (struct prog *prog)
2448{ 2452{
@@ -2478,12 +2482,83 @@ prog_activate_listener (struct prog *prog)
2478 } 2482 }
2479 return 0; 2483 return 0;
2480} 2484}
2485
2486/* Starting at PROG, find first program component marked for termination. */
2487static struct prog *
2488prog_to_stop (struct prog *prog)
2489{
2490 for (; prog; prog = prog->next)
2491 if (IS_COMPONENT (prog) && prog->v.p.stop)
2492 break;
2493 return prog;
2494}
2495
2496#define DIAG_CON \
2497 (init_process ? (DIAG_TO_STDERR|DIAG_REOPEN_LOG) : diag_output)
2481 2498
2499/* Stop all program components marked for termination. Wait at most
2500 2*shutdown_timeout seconds. */
2482void 2501void
2483progman_stop_tag (const char *name) 2502progman_gc ()