Let's say for instance that I create a problem that purposely blocks
the OS from shutting down (maybe a while(1) could do it ?)
Nope. It won't work. A process may not ignore some signals such as SIGKILL and SIGSTOP, except for init
.
In general, you can send SIGKILL immediately after SIGTERM: there is no standard delay to let the application terminate. However, it's wise to give such application a chance to neatly close itself before the kernel will do that without further notifications.
More information here.
What concerns the system shutdown procedure is a little different. Indeed, it is the init
system that decides how and when to take action; the OS helps the init daemon in this operation but indirectly (delivering signals, cleaning up resources and so on).
So, it turns out it's implementation dependent. Analyzing systemd-217, it seems to wait for 10s after sending SIGTERM.
From src/core/shutdown.c in main
log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true);
log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false);
From src/core/killall.c in broadcast_signal
killall(sig, pids, send_sighup);
[...]
if (wait_for_exit)
wait_for_children(pids, &mask);
Continuing, in wait_for_children
until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC;
[...]
k = sigtimedwait(mask, NULL, &ts);
if (k != SIGCHLD)
where TIMEOUT_USER
is #define TIMEOUT_USEC (10 * USEC_PER_SEC)
As you can see, systemd waits for SIGCHLD which would indicate the child has terminated, because most of the processes running are systemd's children.