Are there suspend\resume signals in Linux? - linux

My application needs to react on hibernation mode so it can do some action on suspending and other actions on resuming. I've found some distributive-specific ways to achieve it(Upower + DBus) but didn't find anything universal. Is there a way to do it?
Thanks!

A simple solution to this is to use a self-pipe. Open up a pipe and periodically write timestamps to it. select on this pipe to read the timestamps and compare them to the current time. When there is a big gap, that means you have just woken up from system suspension or hibernate mode.
As for the other way around, there is not much time when the lid is closed and it flips the switch.
If you really need to act on suspend, then you will need to set powersave hooks like this https://help.ubuntu.com/community/PowerManagement/ReducedPower in pm-utils. It could be as simple as
kill -1 `cat mypid` ; sleep 1
Your process would then trap SIGHUP and do what needs to be done to prepare for suspension. The sleep delays the process long enough for your program to react to the signal.

I believe you are looking for SIGSTOP and SIGCONT signals. You can send these to a running process like so:
kill -STOP pid
sleep 60
kill -CONT pid

Related

when will /proc/<pid> be removed?

Process A opened && mmaped thousand of files when running. Then killl -9 <pid of process A> is issued. Then I have a question about the sequence of below two events.
a) /proc/<pid of process A> cannot be accessed.
b) all files opened by process A are closed.
More background about the question:
Process A is a multi-thread background service. It is started by cmd ./process_A args1 arg2 arg3.
There is also a watchdog process which checked whether process A is still alive periodically(every 1 second). If process A is dead, then restart it. The way watchdog checks process A is as below.
1) collect all numerical subdir under /proc/
2) compares /proc/<all-pids>/cmdline with cmdline of process A. If these is a /proc/<some-pid>/cmdline matches, then process A is alive and do nothing, otherwise restart process A.
process A will do below stuff when doing initialization.
1) open fileA
2) flock fileA
3) mmap fileA into memory
4) close fileA
process A will mmap thousand of files after initialization.
after several minutes, kill -9 <pid of process A> is issued.
watchdog detect the death of process A, restart it. But sometimes process A stuck at step 2 flock fileA. After some debugging, we found that unlock of fileA is executed when process A is killed. But sometimes this event will happen after step 2 flock fileA of new process.
So we guess the way to check process alive by monitor /proc/<pid of process A>
is not correct.
then kill -9 is issued
This is bad habit. You'll better send a SIGTERM first. Because well behaved processes and well designed programs can catch it (and exit nicely and properly when getting a SIGTERM...). In some cases, I even recommend: sending SIGTERM. Wait two or three seconds. sending SIGQUIT. Wait two seconds. At last, send a SIGKILL signal (for those bad programs who have not been written properly or are misbehaving). A few seconds later, you could send a SIGKILL. Read signal(7) and signal-safety(7). In multi-threaded, but Linux specific, programs, you might use signalfd(2) or the pipe(7) to self trick (well explained in Qt documentation, but not Qt specific).
If your Linux system is systemd based, you could imagine your program-A is started with systemd facilities. Then you'll use systemd facilities to "communicate" with it. In some ways (I don't know the details), systemd is making signals almost obsolete. Notice that signals are not multi-thread friendly and have been designed, in the previous century, for single-thread processes.
we guess the way to check process alive by monitor /proc/ is not correct.
The usual (and faster, and "atomic" enough) way to detect the existence of a process (on which you have enough privileges, e.g. which runs with your uid/gid) is to use kill(2) with a signal number (the second argument to kill) of 0. To quote that manpage:
If sig is 0, then no signal is sent, but existence and permission
checks are still performed; this can be used to check for the
existence of a process ID or process group ID that the caller is
permitted to signal.
Of course, that other process can still terminate before any further interaction with it. Because Linux has preemptive scheduling.
You watchdog process should better use kill(pid-of-process-A, 0) to check existence and liveliness of that process-A. Using /proc/pid-of-process-A/ is not the correct way for that.
And whatever you code, that process-A could disappear asynchronously (in particular, if it has some bug that gives a segmentation fault). When a process terminates (even with a segmentation fault) the kernel is acting on its file locks (and "releases" them).
Don't scan /proc/PID to find out if a specific process has terminated. There are lots of better ways to do that, such as having your watchdog program actually launch the server program and wait for it to terminate.
Or, have the watchdog listen on a TCP socket, and have the server process connect to that and send its PID. If either end dies, the other can notice the connect was closed (hint: send a heartbeat packet every so often, to a frozen peer). If the watchdog receives a connection from another server while the first is still running, it can decide to allow it or tell one of the instances to shut down (via TCP or kill()).

Bash: Is it possible to stop a PID from being reused?

Is it possible to stop a PID from being reused?
For example if I run a job myjob in the background with myjob &, and get the PID using PID=$!, is it possible to prevent the linux system from re-using that PID until I have checked that the PID no longer exists (the process has finished)?
In other words I want to do something like:
myjob &
PID=$!
do_not_use_this_pid $PID
wait $PID
allow_use_of_this_pid $PID
The reasons for wanting to do this do not make much sense in the example given above, but consider launching multiple background jobs in series and then waiting for them all to finish.
Some programmer dude rightly points out that no 2 processes may share the same PID. That is correct, but not what I am asking here. I am asking for a method of preventing a PID from being re-used after a process has been launched with a particular PID. And then also a method of re-enabling its use later after I have finished using it to check whether my original process finished.
Since it has been asked for, here is a use case:
launch multiple background jobs
get PID's of background jobs
prevent PID's from being re-used by another process after background job terminates
check for PID's of "background jobs" - ie, to ensure background jobs finish
[note if disabled PID re-use for the PID's of the background jobs those PIDs could not be used by a new process which was launched after a background process terminated]*
re-enable PID of background jobs
repeat
*Further explanation:
Assume 10 jobs launched
Job 5 exits
New process started by another user, for example, they login to a tty
New process has same PID as Job 5!
Now our script checks for Job 5 termination, but sees PID in use by tty!
You can't "block" a PID from being reused by the kernel. However, I am inclined to think this isn't really a problem for you.
but consider launching multiple background jobs in series and then waiting for them all to finish.
A simple wait (without arguments) would wait for all the child processes to complete. So, you don't need to worry about the
PIDs being reused.
When you launch several background process, it's indeed possible that PIDs may be reused by other processes.
But it's not a problem because you can't wait on a process unless it's your child process.
Otherwise, checking whether one of the background jobs you started is completed by any means other than wait is always going to unreliable.
Unless you've retrieved the return value of the child process it will exist in the kernel. That also means that it's pid is bound to it and can't being re-used during that time.
Further suggestion to work around this - if you suspect that a PID assigned to one of your background jobs is reassigned, check it in ps to see if it still is your process with your executable and has PPID (parent PID) 1.
If you are afraid of reusing PID's, which won't happen if you wait as other answers explain, you can use
echo 4194303 > /proc/sys/kernel/pid_max
to decrease your fear ;-)

Can not kill process by kill -9?

I try to kill process by using command "kill -9 pid", but can not succeed. Anybody know how could I kill such process and why I can't kill it ?
The process could be zombie? Its good to check process state using ps command as well if you have permission.
If your process is in an uninterruptable sleep (D) due to hanging in some hardware access, you indeed cannot terminate that process.
Here is another explanation.
Personally, I saw such D states for example when accessing files on a SD card or USB stick when there was a hardware problem. But there are many other scenarios where such a state might occur.

Using appropriate POSIX signals

I am currently working on a project which has a daemon process that looks at a queue of tasks, runs those tasks, and then collects information about those tasks. In some cases, the daemon must "kill" a task if it has taken too long to run.
The explanation for SIGTERM is "termination signal" but that's not very informative. I would like to use the most appropriate signal for this.
What is the most appropriate POSIX signal number to use for telling a process "you took too much time to run so you need to stop now"?
If you're in control of the child processes, you can pretty much do as you please, but SIGTERM is the self-documenting signal for this. It asks a process to terminate, politely: the process chooses how to handle the signal and may perform cleanup actions before actually exiting (or may ignore the signal).
The standard way to kill a process, then, is to first send a SIGTERM; then wait for it to terminate with a grace period of, say, five seconds (longer if termination can take a long time, e.g. because of massive disk I/O). If the grace period has expired, send a SIGKILL. That's the "hard" version of SIGTERM and cannot be ignored, but also leaves the process no chance of neatly cleaning up after itself. Having to send a SIGKILL should be considered an issue with the child process and reported as such.
Usually you'll first send SIGTERM to a process. When the process recives this signal it is able to clean up some things an then terminate itself:
kill -15 PID_OF_PROCESS # 15 means SIGTERM
You can check if the process is still running by sending the 0 signal to it's pid.
kill -0 PID_OF_PROCESS # 0 means 0 :)
if [ "$?" == "0" ] ; then
echo "the process is still running"
fi
However, you'll need some grace period to let the process clean up. If the process didn't terminated itself after a grace period, you kill it using SIGKILL this signal can't be handled by the process and the OS will terminate the process immediately.
kill -9 PID_OF_PROCESS # 9 means SIGKILL, means DIE!

Which is the better way to restart a daemontools service?

You've pushed a code update to a daemontools service and want to restart it so it picks up the changes. The service itself is simple and has no built-in signal handling. Which way is better?
svc -d; sleep 5; svc -u
Sends TERM and then CONT. Waits for the service to actually exit, and then restarts it.
svc -h
Sends a HUP signal. The process will die on reception of the signal, and daemontools will restart it.
I've always done some variation on the first, but somebody pointed out today we could actually do the HUP just as well, and I like that better, but I've been doing it the other way so long I can't remember if there was a reason.
I thought it might be because a process in uninterruptible sleep waiting on I/O ignores signals, but according to wikipedia, "When the process is sleeping uninterruptibly, signals accumulated during the sleep will be noticed when the process returns from the system call or trap."
Anybody have an informed opinion on best practice?
It would appear that option 2 (sending a HUP signal) is somewhat cleaner, but in the end, both will get the job done and neither is inherently superior.
Send SIGHUP. It's shorter to type and won't make you wait as long.

Resources