
Signals: A Server Admin's Best Friend
TLDR;
If I ever get a dog, I am going to consider naming it Signal. Not after the messaging app, but after the concept of process manipulation.
Processes & Signals
When it comes to administering Linux and FreeBSD systems, I have often found myself needing to recall the specific "signals" that a process can be sent. A "process" is simply a virtual runtime that the kernel (brain of the operating system) can swap on and off of the processor and memory of the computer. So the process holds information about a program, and it's running state, and what files it has open, and importantly, it has a memory footprint. Some processes require more or less memory.
Well, for my specific use case that I found myself in, I was needing to pause a process, and then resume it at a later time. I knew that I could do this using signals.
You can send a signal to a process to invoke a change. Here are the common signals:
- 15: terminate
- 9: kill
Notice that each signal has an associated number. So you can either use the name or number of a signal when sending them. The terminate
signal is for "nicely" asking a program to end. The kill
signalis for harshly stopping a process as soon as possible. So it could potentially be more dangerous. I try to use
terminate` when possible and if needed.
Well, the interesting thing about signals, is that there is many more than just kill
and terminate
! Here is a selection of signals from the FreeBSD signal(3) man-page documentation:
1 SIGHUP terminate process terminal line hangup
2 SIGINT terminate process interrupt program
3 SIGQUIT create core image quit program
...
9 SIGKILL terminate process kill program
10 SIGBUS create core image bus error
11 SIGSEGV create core image segmentation violation
...
15 SIGTERM terminate process software termination signal
...
17 SIGSTOP stop process stop (cannot be caught or
ignored)
18 SIGTSTP stop process stop signal generated from
keyboard
19 SIGCONT discard signal continue after stop
...
30 SIGUSR1 terminate process User defined signal 1
31 SIGUSR2 terminate process User defined signal 2
...
Stopping & Continuing
Although I haven't used all the signals, I have used some for various purposes. Some programs expect the user to send a signal for certain functionality. In any case, within this list of signals I find what I need:
- 17: Stop, or SIGSTOP
- 19: Continue, or SIGCONT
By sending the SIGSTOP signal I can stop a process from being scheduled on the processor, and effectively pause it. Then I can later send the SIGCONT signal to continue the process.
Sending Signals
You can send signals to a process using the kill
command. Yes, the name of the utility is the same as the most dangerous signal to send. Maybe that is for a reason? It almost seems counter-intuitive, as it seems that kill
would just stop a process. But you can use the kill
utility for a variety of things, sending whatever available signal you like. There is another utility called pkill
, which accepts a process name instead of a process ID, which can potentially make it easier to send a signal if you don't want to look for the process ID.
So you might pause and resume a process by doing this:
# Pause
pkill -SIGSTOP process_name
# Resume
pkill -SIGCONT process_name
User Defined
If you are a programmer, you may have noticed the SIGUSR1
and SIGUSR2
signals. You can catch these signals within your program and setup your own handlers. Well, you can catch whatever signal you like really, but these are set apart for that purpose.
The Unix Way
Sending signals to processes has been around for a long time! So you'll find it in FreeBSD, OpenBSD, Linux, and other nix variants. I have always admired this model, as the "process" container within the operating system is all packaged up, and you can speak to that process in a number of ways. If the process has no listening network socket, or no file socket to communicate with, then the operating system can still do something with it. You could even write a program that only accepts signals, and has no other interface. You could send SIGUSR1 to cause the program to do one thing, or SIGUSR2 to do another.
An interesting side note, the process itself is a container. So I have found Linux containers, such as docker, lxc, or podman, to be somewhat redundant. Yes you can package up specific libraries and things, but calling a Linux container a container seems odd. They are simply just processes with unique namespaces to isolate their processing abilities away from the system.