I want to script an alarm to be triggered when any of crucial to me processes enters a D state (uninterruptible sleep).
In order to test it, I want to have a dummy script to enter D state and trigger the alarm.
How that can be achieved? Maybe with some one-liner?
On Linux, you can reliably do this using vfork
(see this article for more information about how that works). As an example:
#include <unistd.h>
__attribute__((noinline)) static void run_child(void)
{
pause();
_exit(0);
}
int main(void)
{
pid_t pid = vfork();
if (pid == 0) {
run_child();
} else if (pid < 0) {
return 1;
}
return 0;
}
__attribute__((noinline))
is a good idea in order to make sure that the stack space used in the child is separate from the stack space used by the parent. By preventing inlining, we ensure that the function creates a distinct stack frame on entry, and in the context of the vfork()e
d child, this means that any stack manipulation occurs neatly in a separate frame, and not in the parent's stack frame. Without it, the compiler may perform optimisations that result in interleaved data between the parent and child, which could result in stack corruption when the parent resumes.
This will then enter D state until a terminal signal is sent:
% cc -o dstate dstate.c
% ./dstate & sleep 0.1; ps -o pid,state,cmd -p "$!"
[1] 780629
PID S CMD
780629 D ./dstate
% kill "$!"
[1] + terminated ./dstate