What signal is sent to running programs / scripts on shutdown?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







3















Right now I have the following:





# this function is meant for future script expansions
# its purpose is clear, i.e. to clean up some temp files
# now, it is doing nothing, just a special null command
cleanup_on_signal() { :; }

# define functions to handle signals
# treat them as errors with appropriate messages
# example calls:
# kill -15 this_script_name # POSIX, all shells compatible
# kill -TERM this_script_name # Bash and alike - newer shells
signal_handler_HUP() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGHUP (1).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_INT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGINT (2).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_QUIT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGQUIT (3).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_ABRT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGABRT (6).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_TERM() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGTERM (15).\n\tClean-up finished.\n\tTerminating. Bye!"; }

# use the above functions as signal handlers;
# note that the SIG* constants are undefined in POSIX,
# and numbers are to be used for the signals instead
trap 'signal_handler_HUP' 1; trap 'signal_handler_INT' 2; trap 'signal_handler_QUIT' 3; trap 'signal_handler_ABRT' 6; trap 'signal_handler_TERM' 15


I want the script to terminate tidily on shutdown, which right now it does.



But I opened one suggestion of a colleague to issue a question on CTRL+C instead of quitting to shell.



I don't want to turn off the machine, I don't do that often, anyway:



What signal is sent to running programs / scripts on shutdown?










share|improve this question























  • It is SIGTERM. see unix.stackexchange.com/questions/10231/…

    – Rui F Ribeiro
    Feb 10 at 11:43













  • I think, when the init manager (systemd/whatever) does not do their job on some process, then the remaining processes get a SIGTERM. The ones that do not obey SIGTERM, are then sent a SIGKILL. The system makes an effort to shutdown as cleanly as possible.

    – Rui F Ribeiro
    Feb 10 at 11:49













  • It is a pleasure too, enjoy your day.

    – Rui F Ribeiro
    Feb 10 at 12:19











  • Added some shutdown() snippet source.

    – Rui F Ribeiro
    Feb 10 at 12:25




















3















Right now I have the following:





# this function is meant for future script expansions
# its purpose is clear, i.e. to clean up some temp files
# now, it is doing nothing, just a special null command
cleanup_on_signal() { :; }

# define functions to handle signals
# treat them as errors with appropriate messages
# example calls:
# kill -15 this_script_name # POSIX, all shells compatible
# kill -TERM this_script_name # Bash and alike - newer shells
signal_handler_HUP() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGHUP (1).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_INT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGINT (2).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_QUIT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGQUIT (3).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_ABRT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGABRT (6).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_TERM() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGTERM (15).\n\tClean-up finished.\n\tTerminating. Bye!"; }

# use the above functions as signal handlers;
# note that the SIG* constants are undefined in POSIX,
# and numbers are to be used for the signals instead
trap 'signal_handler_HUP' 1; trap 'signal_handler_INT' 2; trap 'signal_handler_QUIT' 3; trap 'signal_handler_ABRT' 6; trap 'signal_handler_TERM' 15


I want the script to terminate tidily on shutdown, which right now it does.



But I opened one suggestion of a colleague to issue a question on CTRL+C instead of quitting to shell.



I don't want to turn off the machine, I don't do that often, anyway:



What signal is sent to running programs / scripts on shutdown?










share|improve this question























  • It is SIGTERM. see unix.stackexchange.com/questions/10231/…

    – Rui F Ribeiro
    Feb 10 at 11:43













  • I think, when the init manager (systemd/whatever) does not do their job on some process, then the remaining processes get a SIGTERM. The ones that do not obey SIGTERM, are then sent a SIGKILL. The system makes an effort to shutdown as cleanly as possible.

    – Rui F Ribeiro
    Feb 10 at 11:49













  • It is a pleasure too, enjoy your day.

    – Rui F Ribeiro
    Feb 10 at 12:19











  • Added some shutdown() snippet source.

    – Rui F Ribeiro
    Feb 10 at 12:25
















3












3








3








Right now I have the following:





# this function is meant for future script expansions
# its purpose is clear, i.e. to clean up some temp files
# now, it is doing nothing, just a special null command
cleanup_on_signal() { :; }

# define functions to handle signals
# treat them as errors with appropriate messages
# example calls:
# kill -15 this_script_name # POSIX, all shells compatible
# kill -TERM this_script_name # Bash and alike - newer shells
signal_handler_HUP() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGHUP (1).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_INT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGINT (2).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_QUIT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGQUIT (3).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_ABRT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGABRT (6).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_TERM() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGTERM (15).\n\tClean-up finished.\n\tTerminating. Bye!"; }

# use the above functions as signal handlers;
# note that the SIG* constants are undefined in POSIX,
# and numbers are to be used for the signals instead
trap 'signal_handler_HUP' 1; trap 'signal_handler_INT' 2; trap 'signal_handler_QUIT' 3; trap 'signal_handler_ABRT' 6; trap 'signal_handler_TERM' 15


I want the script to terminate tidily on shutdown, which right now it does.



But I opened one suggestion of a colleague to issue a question on CTRL+C instead of quitting to shell.



I don't want to turn off the machine, I don't do that often, anyway:



What signal is sent to running programs / scripts on shutdown?










share|improve this question














Right now I have the following:





# this function is meant for future script expansions
# its purpose is clear, i.e. to clean up some temp files
# now, it is doing nothing, just a special null command
cleanup_on_signal() { :; }

# define functions to handle signals
# treat them as errors with appropriate messages
# example calls:
# kill -15 this_script_name # POSIX, all shells compatible
# kill -TERM this_script_name # Bash and alike - newer shells
signal_handler_HUP() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGHUP (1).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_INT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGINT (2).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_QUIT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGQUIT (3).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_ABRT() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGABRT (6).\n\tClean-up finished.\n\tTerminating. Bye!"; }
signal_handler_TERM() { cleanup_on_signal; print_error_and_exit "\ntrap()" "Caught SIGTERM (15).\n\tClean-up finished.\n\tTerminating. Bye!"; }

# use the above functions as signal handlers;
# note that the SIG* constants are undefined in POSIX,
# and numbers are to be used for the signals instead
trap 'signal_handler_HUP' 1; trap 'signal_handler_INT' 2; trap 'signal_handler_QUIT' 3; trap 'signal_handler_ABRT' 6; trap 'signal_handler_TERM' 15


I want the script to terminate tidily on shutdown, which right now it does.



But I opened one suggestion of a colleague to issue a question on CTRL+C instead of quitting to shell.



I don't want to turn off the machine, I don't do that often, anyway:



What signal is sent to running programs / scripts on shutdown?







linux shell-script signals shutdown






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 10 at 11:41









VlastimilVlastimil

8,5781566148




8,5781566148













  • It is SIGTERM. see unix.stackexchange.com/questions/10231/…

    – Rui F Ribeiro
    Feb 10 at 11:43













  • I think, when the init manager (systemd/whatever) does not do their job on some process, then the remaining processes get a SIGTERM. The ones that do not obey SIGTERM, are then sent a SIGKILL. The system makes an effort to shutdown as cleanly as possible.

    – Rui F Ribeiro
    Feb 10 at 11:49













  • It is a pleasure too, enjoy your day.

    – Rui F Ribeiro
    Feb 10 at 12:19











  • Added some shutdown() snippet source.

    – Rui F Ribeiro
    Feb 10 at 12:25





















  • It is SIGTERM. see unix.stackexchange.com/questions/10231/…

    – Rui F Ribeiro
    Feb 10 at 11:43













  • I think, when the init manager (systemd/whatever) does not do their job on some process, then the remaining processes get a SIGTERM. The ones that do not obey SIGTERM, are then sent a SIGKILL. The system makes an effort to shutdown as cleanly as possible.

    – Rui F Ribeiro
    Feb 10 at 11:49













  • It is a pleasure too, enjoy your day.

    – Rui F Ribeiro
    Feb 10 at 12:19











  • Added some shutdown() snippet source.

    – Rui F Ribeiro
    Feb 10 at 12:25



















It is SIGTERM. see unix.stackexchange.com/questions/10231/…

– Rui F Ribeiro
Feb 10 at 11:43







It is SIGTERM. see unix.stackexchange.com/questions/10231/…

– Rui F Ribeiro
Feb 10 at 11:43















I think, when the init manager (systemd/whatever) does not do their job on some process, then the remaining processes get a SIGTERM. The ones that do not obey SIGTERM, are then sent a SIGKILL. The system makes an effort to shutdown as cleanly as possible.

– Rui F Ribeiro
Feb 10 at 11:49







I think, when the init manager (systemd/whatever) does not do their job on some process, then the remaining processes get a SIGTERM. The ones that do not obey SIGTERM, are then sent a SIGKILL. The system makes an effort to shutdown as cleanly as possible.

– Rui F Ribeiro
Feb 10 at 11:49















It is a pleasure too, enjoy your day.

– Rui F Ribeiro
Feb 10 at 12:19





It is a pleasure too, enjoy your day.

– Rui F Ribeiro
Feb 10 at 12:19













Added some shutdown() snippet source.

– Rui F Ribeiro
Feb 10 at 12:25







Added some shutdown() snippet source.

– Rui F Ribeiro
Feb 10 at 12:25












1 Answer
1






active

oldest

votes


















7














While on shutdown the running processes are first told to stop by init(from sendsigs on old implementations, according to @JdeBP)/systemd.



The remaining processes, if any, are sent a SIGTERM. The ones that ignore SIGTERM or do not finish on time, are shortly thereafter sent a SIGKILL by init/systemd.



Those actions are meant to guarantee a stable/clean shutdown (as possible).



Out of curiosity, see the report of a related (old) systemd bug:



Bug 1352264 - systemd immediately sends SIGKILL after SIGTERM during shutdown




systemd immediately sends SIGKILL after SIGTERM during shutdown,
there's no window of opportunity for processes to terminate




Also from shutdown.c/main():




    disable_coredumps();

log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true, arg_timeout);

log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false, arg_timeout);



Also from sysvinit 2.94 sources/init.c, here is the code around a SIGTERM round. If any process(es) were sent a SIGTERM, test each second during 5 seconds to see if there are any processes remaining. Leave the wait if in one of those tests none process is found, or send SIGKILL to the remaining process(es) after the 5 seconds are up.



        switch(round) { 
case 0: /* Send TERM signal */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the TERM signal");
kill(-(ch->pid), SIGTERM);
foundOne = 1;
break;
case 1: /* Send KILL signal and collect status */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the KILL signal");
kill(-(ch->pid), SIGKILL);
break;
}
talk = 0;

}
/*
* See if we have to wait 5 seconds
*/
if (foundOne && round == 0) {
/*
* Yup, but check every second if we still have children.
*/
for(f = 0; f < sleep_time; f++) {
for(ch = family; ch; ch = ch->next) {
if (!(ch->flags & KILLME)) continue;
if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE))
break;
}
if (ch == NULL) {
/*
* No running children, skip SIGKILL
*/
round = 1;
foundOne = 0; /* Skip the sleep below. */
break;
}
do_sleep(1);
}
}
}

/*
* Now give all processes the chance to die and collect exit statuses.
*/
if (foundOne) do_sleep(1)
for(ch = family; ch; ch = ch->next)
if (ch->flags & KILLME) {
if (!(ch->flags & ZOMBIE))
initlog(L_CO, "Pid %d [id %s] seems to hang", ch->pid,
ch->id);
else {
INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
ch->pid, ch->id);
ch->flags &= ~RUNNING;
if (ch->process[0] != '+')
write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
}
}

/*
* Both rounds done; clean up the list.
*/





share|improve this answer


























  • It's sendsigs, not init, in the van Smoorenburg system.

    – JdeBP
    Feb 10 at 15:18











  • @JdeBP Thanks, will check it better later on.

    – Rui F Ribeiro
    Feb 10 at 15:25






  • 1





    I love the details, great answer!

    – Vlastimil
    Feb 10 at 16:31











  • Ah, I also gained something from it, know I know when had problems in some situations, why it did take longer to shutdown. (edit the answer about the sysV code)

    – Rui F Ribeiro
    Feb 10 at 16:45






  • 1





    If you need more than 5 seconds to shutdown, make your program an systemd service, this allows up to 90 seconds with the default settings

    – Ferrybig
    Feb 10 at 20:03












Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f499761%2fwhat-signal-is-sent-to-running-programs-scripts-on-shutdown%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









7














While on shutdown the running processes are first told to stop by init(from sendsigs on old implementations, according to @JdeBP)/systemd.



The remaining processes, if any, are sent a SIGTERM. The ones that ignore SIGTERM or do not finish on time, are shortly thereafter sent a SIGKILL by init/systemd.



Those actions are meant to guarantee a stable/clean shutdown (as possible).



Out of curiosity, see the report of a related (old) systemd bug:



Bug 1352264 - systemd immediately sends SIGKILL after SIGTERM during shutdown




systemd immediately sends SIGKILL after SIGTERM during shutdown,
there's no window of opportunity for processes to terminate




Also from shutdown.c/main():




    disable_coredumps();

log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true, arg_timeout);

log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false, arg_timeout);



Also from sysvinit 2.94 sources/init.c, here is the code around a SIGTERM round. If any process(es) were sent a SIGTERM, test each second during 5 seconds to see if there are any processes remaining. Leave the wait if in one of those tests none process is found, or send SIGKILL to the remaining process(es) after the 5 seconds are up.



        switch(round) { 
case 0: /* Send TERM signal */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the TERM signal");
kill(-(ch->pid), SIGTERM);
foundOne = 1;
break;
case 1: /* Send KILL signal and collect status */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the KILL signal");
kill(-(ch->pid), SIGKILL);
break;
}
talk = 0;

}
/*
* See if we have to wait 5 seconds
*/
if (foundOne && round == 0) {
/*
* Yup, but check every second if we still have children.
*/
for(f = 0; f < sleep_time; f++) {
for(ch = family; ch; ch = ch->next) {
if (!(ch->flags & KILLME)) continue;
if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE))
break;
}
if (ch == NULL) {
/*
* No running children, skip SIGKILL
*/
round = 1;
foundOne = 0; /* Skip the sleep below. */
break;
}
do_sleep(1);
}
}
}

/*
* Now give all processes the chance to die and collect exit statuses.
*/
if (foundOne) do_sleep(1)
for(ch = family; ch; ch = ch->next)
if (ch->flags & KILLME) {
if (!(ch->flags & ZOMBIE))
initlog(L_CO, "Pid %d [id %s] seems to hang", ch->pid,
ch->id);
else {
INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
ch->pid, ch->id);
ch->flags &= ~RUNNING;
if (ch->process[0] != '+')
write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
}
}

/*
* Both rounds done; clean up the list.
*/





share|improve this answer


























  • It's sendsigs, not init, in the van Smoorenburg system.

    – JdeBP
    Feb 10 at 15:18











  • @JdeBP Thanks, will check it better later on.

    – Rui F Ribeiro
    Feb 10 at 15:25






  • 1





    I love the details, great answer!

    – Vlastimil
    Feb 10 at 16:31











  • Ah, I also gained something from it, know I know when had problems in some situations, why it did take longer to shutdown. (edit the answer about the sysV code)

    – Rui F Ribeiro
    Feb 10 at 16:45






  • 1





    If you need more than 5 seconds to shutdown, make your program an systemd service, this allows up to 90 seconds with the default settings

    – Ferrybig
    Feb 10 at 20:03
















7














While on shutdown the running processes are first told to stop by init(from sendsigs on old implementations, according to @JdeBP)/systemd.



The remaining processes, if any, are sent a SIGTERM. The ones that ignore SIGTERM or do not finish on time, are shortly thereafter sent a SIGKILL by init/systemd.



Those actions are meant to guarantee a stable/clean shutdown (as possible).



Out of curiosity, see the report of a related (old) systemd bug:



Bug 1352264 - systemd immediately sends SIGKILL after SIGTERM during shutdown




systemd immediately sends SIGKILL after SIGTERM during shutdown,
there's no window of opportunity for processes to terminate




Also from shutdown.c/main():




    disable_coredumps();

log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true, arg_timeout);

log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false, arg_timeout);



Also from sysvinit 2.94 sources/init.c, here is the code around a SIGTERM round. If any process(es) were sent a SIGTERM, test each second during 5 seconds to see if there are any processes remaining. Leave the wait if in one of those tests none process is found, or send SIGKILL to the remaining process(es) after the 5 seconds are up.



        switch(round) { 
case 0: /* Send TERM signal */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the TERM signal");
kill(-(ch->pid), SIGTERM);
foundOne = 1;
break;
case 1: /* Send KILL signal and collect status */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the KILL signal");
kill(-(ch->pid), SIGKILL);
break;
}
talk = 0;

}
/*
* See if we have to wait 5 seconds
*/
if (foundOne && round == 0) {
/*
* Yup, but check every second if we still have children.
*/
for(f = 0; f < sleep_time; f++) {
for(ch = family; ch; ch = ch->next) {
if (!(ch->flags & KILLME)) continue;
if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE))
break;
}
if (ch == NULL) {
/*
* No running children, skip SIGKILL
*/
round = 1;
foundOne = 0; /* Skip the sleep below. */
break;
}
do_sleep(1);
}
}
}

/*
* Now give all processes the chance to die and collect exit statuses.
*/
if (foundOne) do_sleep(1)
for(ch = family; ch; ch = ch->next)
if (ch->flags & KILLME) {
if (!(ch->flags & ZOMBIE))
initlog(L_CO, "Pid %d [id %s] seems to hang", ch->pid,
ch->id);
else {
INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
ch->pid, ch->id);
ch->flags &= ~RUNNING;
if (ch->process[0] != '+')
write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
}
}

/*
* Both rounds done; clean up the list.
*/





share|improve this answer


























  • It's sendsigs, not init, in the van Smoorenburg system.

    – JdeBP
    Feb 10 at 15:18











  • @JdeBP Thanks, will check it better later on.

    – Rui F Ribeiro
    Feb 10 at 15:25






  • 1





    I love the details, great answer!

    – Vlastimil
    Feb 10 at 16:31











  • Ah, I also gained something from it, know I know when had problems in some situations, why it did take longer to shutdown. (edit the answer about the sysV code)

    – Rui F Ribeiro
    Feb 10 at 16:45






  • 1





    If you need more than 5 seconds to shutdown, make your program an systemd service, this allows up to 90 seconds with the default settings

    – Ferrybig
    Feb 10 at 20:03














7












7








7







While on shutdown the running processes are first told to stop by init(from sendsigs on old implementations, according to @JdeBP)/systemd.



The remaining processes, if any, are sent a SIGTERM. The ones that ignore SIGTERM or do not finish on time, are shortly thereafter sent a SIGKILL by init/systemd.



Those actions are meant to guarantee a stable/clean shutdown (as possible).



Out of curiosity, see the report of a related (old) systemd bug:



Bug 1352264 - systemd immediately sends SIGKILL after SIGTERM during shutdown




systemd immediately sends SIGKILL after SIGTERM during shutdown,
there's no window of opportunity for processes to terminate




Also from shutdown.c/main():




    disable_coredumps();

log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true, arg_timeout);

log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false, arg_timeout);



Also from sysvinit 2.94 sources/init.c, here is the code around a SIGTERM round. If any process(es) were sent a SIGTERM, test each second during 5 seconds to see if there are any processes remaining. Leave the wait if in one of those tests none process is found, or send SIGKILL to the remaining process(es) after the 5 seconds are up.



        switch(round) { 
case 0: /* Send TERM signal */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the TERM signal");
kill(-(ch->pid), SIGTERM);
foundOne = 1;
break;
case 1: /* Send KILL signal and collect status */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the KILL signal");
kill(-(ch->pid), SIGKILL);
break;
}
talk = 0;

}
/*
* See if we have to wait 5 seconds
*/
if (foundOne && round == 0) {
/*
* Yup, but check every second if we still have children.
*/
for(f = 0; f < sleep_time; f++) {
for(ch = family; ch; ch = ch->next) {
if (!(ch->flags & KILLME)) continue;
if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE))
break;
}
if (ch == NULL) {
/*
* No running children, skip SIGKILL
*/
round = 1;
foundOne = 0; /* Skip the sleep below. */
break;
}
do_sleep(1);
}
}
}

/*
* Now give all processes the chance to die and collect exit statuses.
*/
if (foundOne) do_sleep(1)
for(ch = family; ch; ch = ch->next)
if (ch->flags & KILLME) {
if (!(ch->flags & ZOMBIE))
initlog(L_CO, "Pid %d [id %s] seems to hang", ch->pid,
ch->id);
else {
INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
ch->pid, ch->id);
ch->flags &= ~RUNNING;
if (ch->process[0] != '+')
write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
}
}

/*
* Both rounds done; clean up the list.
*/





share|improve this answer















While on shutdown the running processes are first told to stop by init(from sendsigs on old implementations, according to @JdeBP)/systemd.



The remaining processes, if any, are sent a SIGTERM. The ones that ignore SIGTERM or do not finish on time, are shortly thereafter sent a SIGKILL by init/systemd.



Those actions are meant to guarantee a stable/clean shutdown (as possible).



Out of curiosity, see the report of a related (old) systemd bug:



Bug 1352264 - systemd immediately sends SIGKILL after SIGTERM during shutdown




systemd immediately sends SIGKILL after SIGTERM during shutdown,
there's no window of opportunity for processes to terminate




Also from shutdown.c/main():




    disable_coredumps();

log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true, arg_timeout);

log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false, arg_timeout);



Also from sysvinit 2.94 sources/init.c, here is the code around a SIGTERM round. If any process(es) were sent a SIGTERM, test each second during 5 seconds to see if there are any processes remaining. Leave the wait if in one of those tests none process is found, or send SIGKILL to the remaining process(es) after the 5 seconds are up.



        switch(round) { 
case 0: /* Send TERM signal */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the TERM signal");
kill(-(ch->pid), SIGTERM);
foundOne = 1;
break;
case 1: /* Send KILL signal and collect status */
if (talk)
initlog(L_CO,
"Sending processes configured via /etc/inittab the KILL signal");
kill(-(ch->pid), SIGKILL);
break;
}
talk = 0;

}
/*
* See if we have to wait 5 seconds
*/
if (foundOne && round == 0) {
/*
* Yup, but check every second if we still have children.
*/
for(f = 0; f < sleep_time; f++) {
for(ch = family; ch; ch = ch->next) {
if (!(ch->flags & KILLME)) continue;
if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE))
break;
}
if (ch == NULL) {
/*
* No running children, skip SIGKILL
*/
round = 1;
foundOne = 0; /* Skip the sleep below. */
break;
}
do_sleep(1);
}
}
}

/*
* Now give all processes the chance to die and collect exit statuses.
*/
if (foundOne) do_sleep(1)
for(ch = family; ch; ch = ch->next)
if (ch->flags & KILLME) {
if (!(ch->flags & ZOMBIE))
initlog(L_CO, "Pid %d [id %s] seems to hang", ch->pid,
ch->id);
else {
INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
ch->pid, ch->id);
ch->flags &= ~RUNNING;
if (ch->process[0] != '+')
write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
}
}

/*
* Both rounds done; clean up the list.
*/






share|improve this answer














share|improve this answer



share|improve this answer








edited Feb 10 at 17:41

























answered Feb 10 at 12:19









Rui F RibeiroRui F Ribeiro

42k1483142




42k1483142













  • It's sendsigs, not init, in the van Smoorenburg system.

    – JdeBP
    Feb 10 at 15:18











  • @JdeBP Thanks, will check it better later on.

    – Rui F Ribeiro
    Feb 10 at 15:25






  • 1





    I love the details, great answer!

    – Vlastimil
    Feb 10 at 16:31











  • Ah, I also gained something from it, know I know when had problems in some situations, why it did take longer to shutdown. (edit the answer about the sysV code)

    – Rui F Ribeiro
    Feb 10 at 16:45






  • 1





    If you need more than 5 seconds to shutdown, make your program an systemd service, this allows up to 90 seconds with the default settings

    – Ferrybig
    Feb 10 at 20:03



















  • It's sendsigs, not init, in the van Smoorenburg system.

    – JdeBP
    Feb 10 at 15:18











  • @JdeBP Thanks, will check it better later on.

    – Rui F Ribeiro
    Feb 10 at 15:25






  • 1





    I love the details, great answer!

    – Vlastimil
    Feb 10 at 16:31











  • Ah, I also gained something from it, know I know when had problems in some situations, why it did take longer to shutdown. (edit the answer about the sysV code)

    – Rui F Ribeiro
    Feb 10 at 16:45






  • 1





    If you need more than 5 seconds to shutdown, make your program an systemd service, this allows up to 90 seconds with the default settings

    – Ferrybig
    Feb 10 at 20:03

















It's sendsigs, not init, in the van Smoorenburg system.

– JdeBP
Feb 10 at 15:18





It's sendsigs, not init, in the van Smoorenburg system.

– JdeBP
Feb 10 at 15:18













@JdeBP Thanks, will check it better later on.

– Rui F Ribeiro
Feb 10 at 15:25





@JdeBP Thanks, will check it better later on.

– Rui F Ribeiro
Feb 10 at 15:25




1




1





I love the details, great answer!

– Vlastimil
Feb 10 at 16:31





I love the details, great answer!

– Vlastimil
Feb 10 at 16:31













Ah, I also gained something from it, know I know when had problems in some situations, why it did take longer to shutdown. (edit the answer about the sysV code)

– Rui F Ribeiro
Feb 10 at 16:45





Ah, I also gained something from it, know I know when had problems in some situations, why it did take longer to shutdown. (edit the answer about the sysV code)

– Rui F Ribeiro
Feb 10 at 16:45




1




1





If you need more than 5 seconds to shutdown, make your program an systemd service, this allows up to 90 seconds with the default settings

– Ferrybig
Feb 10 at 20:03





If you need more than 5 seconds to shutdown, make your program an systemd service, this allows up to 90 seconds with the default settings

– Ferrybig
Feb 10 at 20:03


















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f499761%2fwhat-signal-is-sent-to-running-programs-scripts-on-shutdown%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Human spaceflight

Can not write log (Is /dev/pts mounted?) - openpty in Ubuntu-on-Windows?

張江高科駅