Processes and DaemonsMidnightBSD 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.
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.
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.
By default, ps only shows processes owned by the current user that are attached
to the current terminal:
ps
The output columns are:
?? means no terminal, i.e. a daemon)The most useful set of options is auxww:
ps auxww
a — show processes of all usersu — show username and memory usagex — include daemon processes with no controlling terminalww — do not truncate long command linesTo 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 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:
q — quith — show helps — change the refresh interval (prompts for seconds)k — kill a process by PID (prompts for PID and signal)r — renice a process (prompts for PID and new priority)o — change the sort columnu — filter by usernamem — toggle memory display modep — toggle display of idle processesI — toggle display of per-CPU idle timeTo 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
The STAT column in ps output shows the current state of a process. The primary
state codes are:
R — runnable; currently on a CPU or waiting for oneS — sleeping; waiting for an event such as I/O or a timer, can
be interrupted by a signalD — disk wait (uninterruptible sleep); typically waiting for I/O
to complete. A process stuck in this state usually indicates slow or failing storage.T — stopped; suspended by a signal such as SIGSTOP or by the job
control mechanismZ — zombie; the process has exited but its parent has not yet
collected its exit status via wait(2). A zombie consumes no resources
other than a PID table entry.W — idle (kernel thread)Additional state modifiers that may follow the primary code:
s — session leader (typically the login shell)+ — process is in the foreground process group< — process has raised priorityN — process has reduced priority (niced)L — process has pages locked in memoryOne 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:
SIGTERM (15) — politely request the process to terminate. The
process can catch this signal, flush buffers, close log files, and shut down cleanly.
This is the default signal sent by kill when no signal is specified.SIGKILL (9) — forcibly terminate the process immediately. This
signal cannot be caught or ignored by the process. Use it only after SIGTERM has
failed, as it gives the process no chance to clean up.SIGHUP (1) — "hang up". Many daemons interpret this as an
instruction to reload their configuration file without restarting. For example,
sending SIGHUP to named or nginx reloads the configuration.SIGINT (2) — interrupt. Equivalent to pressing Ctrl+C in a
terminal. Usually causes a process to stop what it is doing and exit.SIGQUIT (3) — quit and produce a core dump if the process does
not catch it. Equivalent to pressing Ctrl+\.SIGSTOP (17) — pause (suspend) the process. Cannot be caught or
ignored. The process resumes when it receives SIGCONT.SIGCONT (19) — resume a stopped process.SIGUSR1 (30) and SIGUSR2 (31) — application-defined
signals. Their meaning varies by program; consult the relevant daemon's documentation.SIGWINCH (28) — terminal window size changed. Sent automatically
when you resize a terminal; programs like top use it to redraw.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.
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.
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
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.
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
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(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
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