selfboot / AnnotatedShadowSocks

Annotated shadowsocks(python version)
Other
3 stars 1 forks source link

Make Single-Instance Daemon #27

Open selfboot opened 7 years ago

selfboot commented 7 years ago

Daemons are processes that live for a long time. They are often started when the system is bootstrapped and terminate only when the system is shut down. Because they don’t have a controlling terminal, we say that they run in the background. And a daemon is not associated with any particular terminal.

How to cause a process to become a daemon

On POSIX-based systems there are specific steps that a process should perform in order to become a daemon.

  1. Call umask to set the file mode creation mask to a known value, usually 0.
  2. Call fork and have the parent exit.
  3. Call setsid to create a new session. The process becomes the leader of a new session, becomes the leader of a new process group, and is disassociated from its controlling terminal.
  4. Change the current working directory to the root directory.
  5. Unneeded file descriptors should be closed.
  6. Set the umask to zero.
  7. Close then reopen stdin, stdout and stderr. Once it is running a daemon should not read from or write to the terminal from which it was launched. The simplest and most effective way to ensure this is to close the file descriptors corresponding to stdin, stdout and stderr. These should then be reopened, either to /dev/null, or if preferred to some other location.

Note that step 2 and 3 are necessary, others are optional and aim to prevent unwanted interactions from happening.

In version 2.6(https://github.com/shadowsocks/shadowsocks/commit/6dbabdea9d70ebbf7f662105c65198f1c4bbade9) , clowwindy forgot to call setsid to create a new session. But fix this problem in commit https://github.com/shadowsocks/shadowsocks/commit/dae2624b307e083bd9fbd70b7bf3a71e47ca3317.

Single-Instance Daemons

Some daemons are implemented so that only a single copy of the daemon should be running at a time for proper operation.

The file and record-locking(#26) mechanism provides the basis for one way to ensure that only one copy of a daemon is running. If each daemon creates a file with a fixed name and places a write lock on the entire file, only one such write lock will be allowed to be created. Successive attempts to create write locks will fail, serving as an indication to successive copies of the daemon that another instance is already running.

File and record locking provides a convenient mutual-exclusion mechanism. If the daemon obtains a write-lock on an entire file, the lock will be removed automatically if the daemon exits. This simplifies recovery, eliminating the need for us to clean up from the previous instance of the daemon.

Each copy of the daemon will try to create a file and write its process ID in the file. This will allow administrators to identify the process easily. If the file is already locked, the lockf function will fail, indicating that the daemon is already running. Otherwise, we truncate the file, write our process ID to it, and return 0. We need to truncate the file, because the previous instance of the daemon might have had a process ID larger than ours, with a larger string length.

Ref
《APUE 3rd》 Chapter 13. Daemon Processes
Daemon.md
Cause a process to become a daemon