Processes and Daemons

Processes and Daemons

Introduction

MidnightBSD is a multi-tasking operating system. Each program running at any one time is called a process. Every running command starts at least one new process and there are a number of system processes that are run by MidnightBSD itself.

Each process is uniquely identified by a number called a process ID (PID). Similar to files, each process has one owner and group, and the owner and group permissions are used to determine which files and devices the process can open. Most processes also have a parent process that started them. For example, the shell is a process, and any command started in the shell is a process that has the shell as its parent process. The exception is a special process called init(8), which is always the first process to start at boot time and which always has a PID of 1. All other processes on the system are ultimately descendants of init.

PIDs are assigned starting at 1, increase up to 99999, then wrap around. A PID is not reassigned if it is already in use. Each process also has a parent PID (PPID) identifying the process that created it. When a parent process exits before its children, the children are re-parented to init.

Daemons

Some programs are not designed to be run with continuous user input and disconnect from the terminal at the first opportunity. For example, a web server responds to web requests rather than user input. Mail servers are another example of this type of application. These types of programs are known as daemons. The term daemon comes from Greek mythology and represents an entity that is neither good nor evil, and which invisibly performs useful tasks. This is why the BSD mascot is a daemon with sneakers and a pitchfork.

There is a convention to name programs that normally run as daemons with a trailing "d". For example, BIND is the Berkeley Internet Name Domain, but the actual program that executes is named named. The Apache web server program is httpd and the SSH server is sshd. This is only a naming convention — the main daemon for the Sendmail application is sendmail, not maild.

Daemons typically start at boot time, run as a dedicated system user with limited privileges, write logs to /var/log, and store their PID in a file under /var/run so that other programs can find and signal them. For example, the nginx web server writes its PID to /var/run/nginx.pid.

Viewing Processes

To see the processes running on the system, use ps(1) or top(1). Use ps for a static snapshot and top for a live updating view.

ps

By default, ps only shows processes owned by the current user that are attached to the current terminal:

ps

The output columns are:

The most useful set of options is auxww:

ps auxww

To show the process tree (parent/child relationships):

ps auxwwd

To find all processes belonging to a specific user:

ps -U username

To find all processes with a given name, pipe through grep:

ps auxww | grep httpd

The pgrep command is a cleaner way to find PIDs by name:

pgrep httpd
top

top displays a live-updating view of the most active processes and system resource usage. It refreshes every two seconds by default.

top

The header section shows:

Useful interactive commands inside top:

To run top with a specific refresh interval (e.g. 5 seconds):

top -s 5

To show only processes belonging to a specific user:

top -U username

Process States

The STAT column in ps output shows the current state of a process. The primary state codes are:

Additional state modifiers that may follow the primary code:

Signals and Killing Processes

One way to communicate with any running process or daemon is to send a signal using kill(1). Signals are numbered integer values with defined meanings. A user can only send a signal to a process they own. Root can send signals to any process.

To send a signal to a process by PID:

kill -SIGNAL PID

The signal can be specified as a name or number. For example, to send SIGTERM to PID 1234:

kill 1234 kill -TERM 1234 kill -15 1234

Common signals:

To see a full list of signals and their numbers:

kill -l

To kill a process by name using pkill (sends SIGTERM by default):

pkill httpd

To send a specific signal by process name:

pkill -HUP named

To kill all processes matching a name as root:

pkill -9 httpd

Never send SIGKILL to init (PID 1). Killing init will halt or reboot the system depending on how the kernel handles it. Likewise, killing core system processes such as devd or the kernel threads visible in ps output can destabilize or crash a running system.

Process Priority

MidnightBSD schedules CPU time among processes using a priority system. Lower priority numbers mean higher priority. The "nice" value is an adjustment to a process's scheduling priority, ranging from -20 (highest priority) to 20 (lowest priority). Regular users can only increase the nice value (lower the priority) of their own processes. Root can set any nice value.

Start a command with a reduced priority (nice value of 10):

nice -n 10 make -j8

Start a command with the maximum reduced priority:

nice -n 20 rsync -av /data /backup

Change the nice value of a running process with renice:

renice +10 1234

Increase the priority of a process (root only):

renice -5 1234

Setting long-running background tasks to a higher nice value prevents them from competing with interactive work for CPU time.

Background Jobs and Job Control

The shell's job control feature lets you run multiple commands from a single terminal session by suspending, resuming, and switching between foreground and background jobs.

Append & to a command to run it in the background immediately:

long_running_command &

The shell prints the job number and PID, for example [1] 4823. The job continues running while you use the shell for other commands.

To suspend a foreground process and return to the shell prompt, press Ctrl+Z. The process is stopped (SIGSTOP) and the shell reports:

[1]+ Stopped long_running_command

To resume a suspended job in the background:

bg %1

To bring a background or suspended job back to the foreground:

fg %1

To list all current jobs in the shell session:

jobs

When you close a terminal, the shell normally sends SIGHUP to all its child processes, terminating them. To start a process that survives terminal logout, use nohup:

nohup long_running_command &

Output that would have gone to the terminal is redirected to nohup.out in the current directory. Alternatively, use disown after starting a background job to remove it from the shell's job table:

long_running_command & disown %1

Managing Daemons with service

MidnightBSD uses the rc framework to start, stop, and manage daemons. The service(8) command is the standard interface for interacting with rc scripts without needing to call the scripts directly.

Start a daemon:

service sshd start

Stop a daemon:

service sshd stop

Restart a daemon (stop then start):

service sshd restart

Reload the daemon's configuration without a full restart (equivalent to SIGHUP for most daemons):

service named reload

Check whether a daemon is running:

service sshd status

List all available rc services:

service -l

List services that are currently enabled in /etc/rc.conf:

service -e

Each daemon has a corresponding rc script in /etc/rc.d/ (base system) or /usr/local/etc/rc.d/ (mports). You can call these scripts directly, but using service is preferred as it sets the correct environment.

Starting Daemons at Boot

Whether a daemon starts at boot is controlled by /etc/rc.conf. Most daemons are disabled by default and must be explicitly enabled. The rc script for each daemon defines a variable name following the pattern daemonname_enable.

To enable the SSH server so it starts at boot, add to /etc/rc.conf:

sshd_enable="YES"

Other common examples:

ntpd_enable="YES"
named_enable="YES"
nginx_enable="YES"
postgresql_enable="YES"

Many daemons also accept configuration flags through a corresponding daemonname_flags variable:

ntpd_flags="-g"

After editing /etc/rc.conf, start the newly enabled service immediately without rebooting:

service sshd start

To check what rc.conf settings are currently active without opening the file:

sysrc sshd_enable

The sysrc(8) command also safely adds or removes values without manually editing /etc/rc.conf:

sysrc sshd_enable="YES" sysrc -x sshd_enable

Detailed Process Information

procstat

procstat(1) provides detailed information about a process that goes beyond what ps shows, including open file descriptors, memory mappings, and kernel stack traces.

Show open files for a process:

procstat -f PID

Show virtual memory mappings:

procstat -v PID

Show the kernel thread stack (useful for diagnosing hangs):

procstat -k PID

Show all available information:

procstat -a PID
fstat

fstat(1) lists open files across all processes or for a specific user. It is useful for finding which process has a file or device open:

fstat /var/log/messages fstat -u username
sysctl

Several sysctl values expose process and system information:

Show the maximum number of processes allowed on the system:

sysctl kern.maxproc

Show the current number of processes:

sysctl kern.nprocs

Show the load averages:

sysctl vm.loadavg