0

I want to understand a little bit better, what a background process is. The question came to live as a result of reading this line of code:

/usr/sbin/rsyslogd -niNONE &

Source

The documentations says:

  -i pid file
         Specify an alternative pid file instead of the default
         one.  This option must be used if multiple instances of
         rsyslogd should run on a single machine. To disable
         writing a pid file, use the reserved name "NONE" (all
         upper case!), so "-iNONE".

-n Avoid auto-backgrounding. This is needed especially if the rsyslogd is started and controlled by init(8).

Source

The ampersand & seems to mean to request that the command is run in the background, see, for example here.

If my understanding is correct, pid files are used with daemons, that is when a program is run in the background.

So on the face value it seems that the command in question first tells the program not to run in the background with -n, then specify NONE for the pid file, to indicate it is not a daemon1, and then right after that specify & to send it into the background.

I cannot make a lot of sense of that. Is the background that the process would normally enter is a different background it is sent to by using &? From all I read, it seems that the only meaning of the background is that shell is not blocked. In this respect asking the process not to auto-background and then background it does not make a lot of sense.

Is there something here I'm missing? What is exactly the background? (And who is responsible for deleting the pid file, while we are at it?)


1 - in a docker container context, where the question arose from, the existence of the pid file can cause problems when the container is stopped and then restarted. It is not clear for me what is responsible for deleting the pid files, some sources suggest that it's the init system, such as systemd, while others imply that it's the program responsibility. However if a process killed with SIGKILL the program might not have an opportunity to delete it, so subsequent container re-start will fail because the pid file will already be there, but is expected not to.

1 Answers1

8

The Unix concept of a background process is part of job control. Job control is the organization of processes around a terminal session.

Daemons normally don't run in a terminal session, therefore they are not background processes in the Unix job control sense, only in the general computing sense of belonging to the machine's "invisible" activity. This is most likely what the rsyslogd documentation is referring to: it's referring to becoming a daemon, and not a job control background process.

In an interactive terminal session, the user manages jobs. Each job is a group of processes (perhaps one), arranged into that group by some piece of software (usually the job control shell). Each job in the session has the terminal as its controlling terminal.

The background/foreground concept has to do with the sharing of the terminal device among these jobs. At any time, one of the process groups is assigned as the foreground process group. It may read characters from the terminal, and send output to the terminal. Other process groups are all background process groups.

The job control shell provides the shuffling of jobs between foreground and background is done with a combination of signaling from the TTY and certain functions like tcsetpgrp.

The foreground process group is not just allowed to read from and write to the terminal, but it also receives TTY-generated signals, like SIGINT from CtrlC, and SIGTSTP from CtrlZ.

Typically, you use CtrlZ to suspend a job into the background and then a job control command like bg to get it to execute in the background.

When you issue CtrlZ, every process in the foreground process group gets a SIGTSTP signal and is suspended. The job control shell detects this change, and makes the library calls to move that job into the background, and make itself the foreground process group. So, the shell now being in the foreground again, it can receive commands from the TTY.

Now you can type bg, and the shell will cause the suspended background job to execute.

The fg command will cause the shell to remove itself from the foreground and place a background job into the foreground again.

Background jobs don't receive the character-driven signals from the TTY like SIGINT from CtrlC. However, when they try to read or write to the terminal, they receive a signal like SIGTTOU and become blocked from that action.

Job control is like a traffic cop, guarding access to the terminal.

It's similar to what window management is in a GUI. In typical GUI, one window has the "keyboard focus". Keystrokes go to that window. So it is with job control: the foreground process group has the "terminal focus", so to speak.

The rsyslogd documentation is almost certainly using the term "background" to actually mean "turn into a daemon" or "daemonize". This is different from "background job" under POSIX job control.

When a server application daemonizes itself automatically it means that if it is run in a terminal session, it takes steps to remove itself from that session. It forks a child and then a grandchild. The child terminates, and so the grandchild becomes orphaned, and a child of the init daemon. That's part of it. The other part of it is that the grandchild will close the standard input, output and error file descriptors. Thus it loses the connection to the TTY. Some other actions may be taken, like changing to some specific working directory.

It makes sense that that rsyslogd doesn't daemonize itself if run by init, since there is no terminal session to dissociate from. (However, rsyslogd could detect that it's not part of a terminal session, and not require the -n flag in that situation.)

Thus, actually, the main use of a do-not-daemonize command line option in a server would be for debugging, with specific reasons like:

  • Perhaps the daemon has some debug trace mode whereby messages get sent to standard output. If you want to watch those messages on your console, you don't want the daemon to close its standard output file descriptor.

  • If you want to debug the daemon under debugger, it is inconvenient if it simply exits, such that the actual daemon activity is happening in a forked grandchild.

  • When you're testing, you may want to exercise job control over the daemon, like terminating it with CtrlC, or suspending with CtrlZ.

  • Sometimes people like to run servers under terminal multiplexing software like GNU Screen or Termux, where the servers run in a terminal session. Auto-daemonization would defeat the purpose of that.

Regarding who is responsible for deleting a PID file: mainly, the service application itself, if it is shut down cleanly. If some master process is managing services, it can know about the paths to their PID files, and clean up after them if they terminate without deleting the file. PID files are typically placed into a directory that is wiped on a reboot, like /var/run, so if the system catastrophically fails and has to be restarted, the restart takes care of the PID files.

Kaz
  • 8,273
  • Thank you for a very detailed answer. Is suspended and background the same thing in the context of job control? – Andrew Savinykh Aug 24 '22 at 08:05
  • @AndrewSavinykh No. Kaz already explained that in the answer. Background jobs are able to run, suspended jobs aren't. – Vilinkameni Aug 24 '22 at 08:45
  • But does it mean that every suspended job is a background job? I'm referring to this part: "Typically, you use CtrlZ to suspend a job into the background" – Andrew Savinykh Aug 24 '22 at 09:37
  • @Vilinkameni "Kaz already explained that in the answer." - why did you mention that? Did you mean that I should not have asked for a clarification, because it was already answered or something else? – Andrew Savinykh Aug 24 '22 at 09:41
  • Yes. Isn't it obvious? Reread the answer more carefully. – Vilinkameni Aug 24 '22 at 09:48
  • I'm referring to this part: "Typically, you use CtrlZ to suspend a job into the background" - it is just semantics. Suspending a job halts its execution, as I already wrote above. Backgrounded jobs which aren't suspended are able to execute. Suspending a job typically returns terminal control to a shell. – Vilinkameni Aug 24 '22 at 09:54