diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-02-19 08:41:12 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-02-19 08:41:12 +0200 |
commit | e6902abfddb4d7b16dc9a4231a3781f354a08cd5 (patch) | |
tree | c634621af2ae765460e010ce83c8492ed4e859bc /src | |
parent | 51a797445a4bfc34ad1ae7ea91e12486d823abda (diff) | |
download | pies-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.c | 32 | ||||
-rw-r--r-- | src/pies.c | 2 | ||||
-rw-r--r-- | src/pies.h | 2 | ||||
-rw-r--r-- | src/prog.h | 5 | ||||
-rw-r--r-- | src/progman.c | 95 | ||||
-rw-r--r-- | src/sysvinit.c | 42 |
6 files changed, 102 insertions, 76 deletions
@@ -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 */ |
362 | static int | 362 | static int |
363 | cb_terminate_prog (struct prog *prog, void *data) | 363 | mark_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 */ | ||
371 | static int | ||
372 | cb_kill_prog (struct prog *prog, void *data) | ||
373 | { | ||
374 | if (prog_is_leftover (prog)) | ||
375 | prog_stop (prog, SIGKILL); | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int | ||
380 | list_is_empty (void *p) | ||
381 | { | ||
382 | struct complist *list = p; | ||
383 | return list->head == NULL; | ||
384 | } | ||
385 | |||
386 | static int | 370 | static int |
387 | list_str_cmp (const void *a, const void *b) | 371 | list_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 */ |
@@ -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) |
@@ -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 | ||
322 | void pies_schedule_children (int op); | 323 | void pies_schedule_children (int op); |
323 | 324 | ||
@@ -330,7 +331,6 @@ void progman_cleanup (int expect_term); | |||
330 | void progman_filter (int (*filter) (struct component *, void *data), | 331 | void progman_filter (int (*filter) (struct component *, void *data), |
331 | void *data); | 332 | void *data); |
332 | int progman_wait_until (int (*cond) (void *), void *data); | 333 | int progman_wait_until (int (*cond) (void *), void *data); |
333 | void progman_stop_tag (const char *name); | ||
334 | int progman_accept (int socket, void *data); | 334 | int progman_accept (int socket, void *data); |
335 | 335 | ||
336 | void progman_create_sockets (void); | 336 | void progman_create_sockets (void); |
@@ -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 | |||
956 | static int | 955 | static int |
957 | prog_open_socket (struct prog *prog) | 956 | prog_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 | |||
1477 | void | 1475 | void |
1478 | progman_recompute_alarm () | 1476 | progman_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 | |||
1514 | void | 1510 | void |
1515 | progman_start () | 1511 | progman_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 | ||
2446 | void | 2450 | void |
2447 | prog_deactivate_listener (struct prog *prog) | 2451 | prog_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. */ | ||
2487 | static struct prog * | ||
2488 | prog_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. */ | ||
2482 | void | 2501 | void |
2483 | progman_stop_tag (const char *name) | 2502 | progman_gc () |