Recent from talks
Contribute something
Nothing was collected or created yet.
Daemon (computing)
View on Wikipedia
In computing, a daemon is a program that runs as a background process, rather than being under the direct control of an interactive user. Customary convention is to name a daemon process with the letter d as a suffix to indicate that it's a daemon. For example, syslogd is a daemon that implements system logging facility, and sshd is a daemon that serves incoming SSH connections.
Even though the concept can apply to many computing systems, the term daemon is used almost exclusively in the context of Unix-based systems. In other contexts, different terms are used for the same concept.
Systems often start daemons at boot time that will respond to network requests, hardware activity, or other programs by performing some task. Daemons such as cron may also perform defined tasks at scheduled times.
Terminology
[edit]In the context of computing, the word is generally pronounced either as /ˈdiːmən/ DEE-mən or /ˈdeɪmən/ DAY-mən.[1]
The term was coined by the programmers at MIT's Project MAC. According to Fernando J. Corbató, who worked on Project MAC around 1963, his team was the first to use the term daemon, inspired by Maxwell's demon, an imaginary agent in physics and thermodynamics that helped to sort molecules, stating, "We fancifully began to use the word daemon to describe background processes that worked tirelessly to perform system chores".[2] Unix systems inherited this terminology. Maxwell's demon is consistent with Greek mythology's interpretation of a daemon as a supernatural being working in the background.
In the general sense, daemon is an older form of the word "demon", from the Greek δαίμων. In the Unix System Administration Handbook Evi Nemeth states the following about daemons:[3]
Many people equate the word "daemon" with the word "demon", implying some kind of satanic connection between UNIX and the underworld. This is an egregious misunderstanding. "Daemon" is actually a much older form of "demon"; daemons have no particular bias towards good or evil, but rather serve to help define a person's character or personality. The ancient Greeks' concept of a "personal daemon" was similar to the modern concept of a "guardian angel"—eudaemonia is the state of being helped or protected by a kindly spirit. As a rule, UNIX systems seem to be infested with both daemons and demons.
Alternative terms include service (used in Windows, from Windows NT onwards, and later also in Linux), started task (IBM z/OS),[4] and ghost job (XDS UTS). Sometimes the more general term server or server process is used, particularly for daemons that operate as part of client-server systems.[5] A daemon that connects to a computer network is a network service.
After the term was adopted for computer use, it was incorrectly[1] rationalized as a backronym for disk and execution monitor.[6][7][8]
Implementations
[edit]Unix-like systems
[edit]In a Unix-like system, the parent process of a daemon is often, but not always, the init process. A daemon is usually created either by the init process directly launching the daemon, by the daemon being run by an initialization script run by init, by the daemon being launched by a super-server launched by init.
The init process in Research Unix and BSD starts daemons from an initialization script. A daemon started as a command in an initialization script must either fork a child process and then immediately exit, or must be run as a background process using &, so that the shell running the initialization script can continue after starting the daemon. In the former case, the daemon process run from the shell exits, thus causing init to adopt the child process that runs as the daemon; in the latter case, when the shell running the initialization script exits, the child daemon process is adopted by init.[9]
The versions of init in System III and in System V can run arbitrary commands and can be configured to run them once or to restart them when they terminate.[10][11][12][13] The former mechanism can be used to run initialization scripts; daemons started from those scripts behave the same as in Research Unix and BSD. The latter mechanism can be used to run daemons directly from init.
A daemon can also be launched from a user's command line. However, daemons launched in that fashion typically must perform other operations, such as dissociating the process from any controlling terminal (tty). Such procedures are often implemented in various convenience routines such as daemon(3). A daemon launched by an initialization script need not do these steps, but doing so allows the daemon to be restarted by a user if it exits;[14] init itself would not restart them.[15] Operations such a daemon must do include:
- Optionally removing unnecessary variables from environment.
- Executing as a background task by forking and exiting (in the parent "half" of the fork). This allows daemon's parent (shell or startup process) to receive exit notification and continue its normal execution.
- Detaching from the invoking session, usually accomplished by a single operation,
setsid():- Dissociating from the controlling tty.
- Creating a new session and becoming the session leader of that session.
- Becoming a process group leader.
- If the daemon wants to ensure that it will not acquire a new controlling tty even by accident (which happens when a session leader without a controlling tty opens a free tty), it may fork and exit again. This means that it is no longer a session leader in the new session, and cannot acquire a controlling tty.
- Setting the root directory (/) as the current working directory so that the process does not keep any directory in use that may be on a mounted file system (allowing it to be unmounted).
- Changing the umask to 0 to allow
open(),creat(), and other operating system calls to provide their own permission masks and not to depend on the umask of the caller. - Redirecting file descriptors 0, 1 and 2 for the standard streams (stdin, stdout and stderr) to /dev/null or a logfile, and closing all the other file descriptors inherited from the parent process.
If the process is started by a super-server daemon, such as inetd, launchd, or systemd, the super-server daemon will perform those functions for the process,[16][17][18] except for old-style daemons not converted to run under systemd and specified as Type=forking[18] and "multi-threaded" datagram servers under inetd.[16]
MS-DOS
[edit]In MS-DOS, daemon-like functionality was implemented as a terminate-and-stay-resident program (TSR).
Windows
[edit]In Windows, a Windows service provides the functionality of a daemon. It runs as a process, usually does not interact with the user (i.e. via monitor, keyboard, or mouse) and may be launched by the operating system at boot time. In Windows 2000 and later versions, a Windows service is configured and controlled via various interfaces including the Control Panel, the Service Control Manager sc command, the net start and net stop commands, PowerShell, or a custom program.
However, any Windows application can perform the role of a daemon, not just a service, and some Windows daemons have the option of running as a normal process.
Mac
[edit]In classic Mac OS, optional features and services were provided by system extensions and control panels – files loaded at startup time that patched the operating system. Later versions of classic Mac OS augmented these with faceless background applications: regular applications that ran in the background. To the user, these were still described as regular system extensions.
The more modern macOS, which is Unix-based, uses daemons but uses the term "services" to designate software that performs functions selected from the Services menu, rather than using that term for daemons, as Windows does.
See also
[edit]References
[edit]- ^ a b Eric S. Raymond. "daemon". The Jargon File. Retrieved 2008-10-22.
- ^ "The Origin of the word Daemon".
- ^ "The BSD Daemon". Freebsd.org. Retrieved 2008-11-15.
- ^ "Glossary of z/OS terms and abbreviations". IBM Documentation. IBM. 31 January 2006.
- ^ "sshd: OpenSSH server process | SSH Academy". www.ssh.com. Retrieved 2023-12-04.
- ^ "Daemon Definition". www.linfo.org.
- ^ "What is a daemon?". UCLA Knowledge Base.
- ^ "Daemon". Kayshav.com.
- ^ "(Unix) daemonization turns out to be quite old". October 3, 2024.
- ^ UNIX User's Manual, Release 3.0 (PDF). June 1980. INIT(8).
- ^ UNIX User's Manual, Release 3.0 (PDF). June 1980. INITTAB(5).
- ^ UNIX System Administrator's Manua Release 5.0 (PDF). June 1982. INIT(1M).
- ^ UNIX User's Manual System V (PDF). January 1983. INITTAB(4).
- ^ "Daemonization in Unix programs is probably about restarting programs". October 5, 2024.
- ^ "Traditionally, init on Unix was not a service manager as such". October 4, 2024.
- ^ a b – FreeBSD System Manager's Manual
- ^ – Darwin and macOS File Formats Manual
- ^ a b "systemd.service". freedesktop.org. Retrieved August 25, 2012.
External links
[edit]- Unix Daemon Server Programming at the Wayback Machine (archived 2019-10-30)
Daemon (computing)
View on GrokipediaFundamentals
Definition
In computing, a daemon is a non-interactive computer program that runs as a background process, executing continuously or triggered on demand to handle system-wide tasks such as processing network requests, managing logs, or scheduling jobs.[3] Unlike user-initiated applications, daemons operate autonomously without requiring direct human intervention, often providing essential services that maintain the operating system's functionality.[4] They are typically found in multitasking environments like Unix-like systems, where they contribute to the modular design by isolating specific functions from the core kernel.[5] Key characteristics of daemons include detachment from any controlling terminal, which prevents them from being interrupted by user input or logout events; operation with reduced privileges when feasible to enhance security; initiation at system boot to ensure availability; and adherence to a naming convention where executable names often end with a "d" suffix, such as httpd for the HTTP daemon.[6][4] This detachment allows daemons to persist across user sessions, emphasizing their role in long-term, persistent system support rather than transient tasks.[7] Daemons differ from foreground processes, which are directly attached to a user's terminal and halt upon terminal closure, and from general services or user applications, which may interact with users or terminate after completing a specific action; instead, daemons prioritize autonomy and endurance to support ongoing infrastructure needs.[7] For instance, syslogd serves as the system logging daemon, capturing and routing messages from the kernel, applications, and other daemons to appropriate files or outputs for auditing and debugging.[8] Similarly, sshd functions as the Secure Shell daemon, listening on network ports to authenticate and manage encrypted remote connections, forking child processes to handle individual sessions securely.[9]History
The term "daemon" in computing was coined in 1963 by Fernando J. Corbató and his team at MIT's Project MAC, drawing inspiration from Maxwell's demon in physics—a hypothetical entity acting as an invisible sorter of molecules to illustrate thermodynamic principles—as a metaphor for background processes that invisibly assist the system.[10] This concept emerged during work on the Compatible Time-Sharing System (CTSS), where the first daemon automated tape backups on an IBM 7094 mainframe, marking the initial use of such invisible helpers in time-sharing environments.[10] Daemons saw early adoption in the Multics operating system during the 1960s and 1970s, where they functioned as background processes managing system services like networking and maintenance under the project name SysDaemon.[11] Developed jointly by MIT, Bell Labs, and General Electric starting in 1964, Multics employed daemons to support its innovative time-sharing and security features, providing reliable, non-interactive operations that foreshadowed their role in multitasking systems.[12] The concept transitioned to Unix in the 1970s, becoming a standard mechanism for handling background tasks in multitasking environments as Unix evolved from Multics influences at Bell Labs. Key milestones included the introduction of the init process around 1972, which served as the parent of all daemons and managed system initialization, and the cron daemon in Version 7 Unix in 1979, enabling scheduled background executions—both integrated into early Berkeley Software Distribution (BSD) releases to enhance system automation.[13] Through the 1980s and 1990s, daemons evolved to support networked environments, exemplified by the inetd super-server in 4.3BSD (1986), which managed incoming connections by spawning specialized daemons for services like FTP and Telnet to optimize resource use.[14] This period also saw the concept influence non-Unix systems, such as the service architecture in Windows NT 3.1 (1993), where background processes analogous to daemons provided system services under a centralized manager, bridging Unix traditions with Microsoft's enterprise focus.[15] Post-2000 developments marked a shift toward more integrated daemon management, highlighted by the introduction of systemd in 2010 for Linux, which unified process supervision, logging, and service dependencies to address limitations in traditional SysV init and Upstart systems. Developed by Lennart Poettering and Kay Sievers, systemd streamlined daemon lifecycle control across distributions, improving boot times and reliability while sparking debates on Unix philosophy adherence.Terminology
Etymology
The term "daemon" in computing derives from the ancient Greek word daímōn (δαίμων), which originally denoted a spirit, divine power, or guiding deity, often neutral or benevolent rather than malevolent.[16] This linguistic root emphasized intermediary supernatural agents that influenced human affairs without inherent evil connotations, as seen in concepts like eudaimonia (well-being guided by a good spirit).[16] In the 19th century, the term was reinterpreted in physics through James Clerk Maxwell's 1867 thought experiment, known as "Maxwell's demon," where an imaginary efficient agent sorts molecules to challenge the second law of thermodynamics by reducing entropy without apparent energy expenditure.[17] This hypothetical entity, described as a tireless sorter operating in the background, provided a metaphorical foundation for later technical uses, portraying it as a helpful, autonomous mechanism rather than anything supernatural or demonic.[1] The adoption of "daemon" in computing occurred in 1963 by programmers at MIT's Project MAC (Mathematics and Computation), who applied it to background processes that ran autonomously to perform system tasks, explicitly drawing inspiration from Maxwell's demon to evoke an impartial, efficient helper.[1] This choice deliberately favored the archaic spelling "daemon" to distance it from the modern English "demon," which carries negative, evil associations from Christian reinterpretations of the Greek term, ensuring the computing usage conveyed neutrality and utility without supernatural implications.[1] The term's mythological roots in Greek lore—where daimones acted as personal guardians or fate dispensers—further reinforced its suitability for invisible, supportive software entities, though the computing application remained firmly rooted in Maxwell's scientific analogy.[16] A common misconception with the false backronym "disk and execution monitor," purportedly explaining daemons as monitors for disk operations and executions, but this is a later rationalization with no historical basis in the term's 1963 coinage or earlier inspirations.[1] While the word has influenced modern literature, such as Philip Pullman's His Dark Materials series (1995–2000), where daemons represent animal manifestations of human souls, these fictional uses postdate and diverge from the technical origins in physics and early computing.[1]Usage and Alternatives
In computing, the term "daemon" is commonly pronounced as /ˈdiːmən/ (DEE-mən), reflecting its origins in early Unix systems, though a regional variant /ˈdeɪmən/ (DAY-mən) is also used by some speakers.[18] To avoid confusion with the supernatural "demon," the pronunciation /ˈdeɪmɒn/ is generally discouraged in technical contexts.[19] A longstanding naming convention for daemons, particularly in Unix-like systems, involves appending the letter "d" to the name of the service they provide, such as ftpd for the File Transfer Protocol daemon or sshd for the Secure Shell daemon.[1] This practice aids in identifying background processes in system logs and process lists.[20] Across different operating systems, equivalents to daemons exist under alternative terminology to describe similar background processes. In Windows and macOS user interfaces, they are typically referred to as "services," managed through tools like the Services console or launchd.[21][22] In IBM z/OS mainframes, the term "started task" denotes batch-initiated background jobs akin to daemons, such as the SYSLOGD process.[23] For MS-DOS environments lacking native multitasking, terminate-and-stay-resident (TSR) programs provided daemon-like functionality by remaining in memory to handle interrupts after the primary program terminated.[24] Originally confined to Unix environments, the concept of daemons has evolved with the rise of hybrid and cross-platform systems, where the term persists in technical documentation and discussions despite the adoption of platform-specific synonyms in user-facing tools.[1]Implementation Principles
Daemonization Process
The daemonization process involves transforming a user-initiated process into a background daemon that operates independently of the controlling terminal and user session. This detachment ensures the process persists beyond the user's login session and runs without interactive input or output. The standard procedure, applicable to Unix-like systems, follows a series of POSIX-compliant system calls to achieve this isolation.[3] The core steps begin with forking a child process using thefork() system call, allowing the parent process to exit while the child continues execution. This initial fork prevents the process from becoming a process group leader with a controlling terminal. The child then invokes setsid() to create a new session, making itself the session leader and process group leader, thereby detaching from any existing terminal. To further ensure no possibility of reacquiring a controlling terminal, a second fork() is performed, creating a grandchild process that is neither a session leader nor a process group leader. The grandchild then changes its working directory to the root filesystem (/) using chdir() to avoid preventing unmounting of filesystems, and resets its file creation mask to 0 with umask(0) for predictable file permissions. Finally, the standard input, output, and error streams (stdin, stdout, stderr) are redirected to /dev/null or log files using dup2() or similar calls, eliminating any ties to the original terminal. To prevent inheritance of unnecessary resources and potential security issues, all other open file descriptors (beyond 0, 1, and 2) are closed, for example, using a loop from 3 up to the system maximum. Error handling is crucial; for instance, if fork() fails due to resource limits, the process should exit with an appropriate error code like EXIT_FAILURE.[3]
// High-level pseudocode for daemonization
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
int daemonize() {
// Step 1: First fork
pid_t pid = fork();
if (pid < 0) {
return -1; // Fork failed
} else if (pid > 0) {
exit(EXIT_SUCCESS); // Parent exits
}
// Child continues
// Step 2: Create new session
if (setsid() < 0) {
return -1;
}
// Step 3: Second fork to ensure no controlling terminal
pid = fork();
if (pid < 0) {
return -1;
} else if (pid > 0) {
exit(EXIT_SUCCESS); // First child exits
}
// Grandchild continues
// Step 4: Reset [umask](/page/Umask)
[umask](/page/Umask)(0);
// Step 5: Change working directory to [root](/page/Root)
if (chdir("/") < 0) {
return -1;
}
// Step 6: Redirect standard streams to /dev/null
int fd = open("/dev/null", O_RDWR);
if (fd < 0) {
return -1;
}
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
if (fd > 2) {
close(fd);
}
// Step 7: Close all other open file descriptors
long maxfd = sysconf(_SC_OPEN_MAX);
for (long i = 3; i < maxfd; i++) {
close((int)i);
}
return 0; // Success
}
// High-level pseudocode for daemonization
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
int daemonize() {
// Step 1: First fork
pid_t pid = fork();
if (pid < 0) {
return -1; // Fork failed
} else if (pid > 0) {
exit(EXIT_SUCCESS); // Parent exits
}
// Child continues
// Step 2: Create new session
if (setsid() < 0) {
return -1;
}
// Step 3: Second fork to ensure no controlling terminal
pid = fork();
if (pid < 0) {
return -1;
} else if (pid > 0) {
exit(EXIT_SUCCESS); // First child exits
}
// Grandchild continues
// Step 4: Reset [umask](/page/Umask)
[umask](/page/Umask)(0);
// Step 5: Change working directory to [root](/page/Root)
if (chdir("/") < 0) {
return -1;
}
// Step 6: Redirect standard streams to /dev/null
int fd = open("/dev/null", O_RDWR);
if (fd < 0) {
return -1;
}
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
if (fd > 2) {
close(fd);
}
// Step 7: Close all other open file descriptors
long maxfd = sysconf(_SC_OPEN_MAX);
for (long i = 3; i < maxfd; i++) {
close((int)i);
}
return 0; // Success
}
SIGHUP signal, often sent upon terminal closure, should be ignored or handled for configuration reloads after detachment, as the daemon no longer has a controlling terminal. Handlers for SIGTERM and SIGINT must be implemented to perform cleanup, such as closing files and releasing resources, before exiting, ensuring orderly shutdowns initiated by administrators.[3]
Privilege reduction enhances security by minimizing the daemon's attack surface after necessary privileged operations, such as binding to ports below 1024. Once these tasks are complete, the daemon drops root privileges using setuid() and setgid() to switch to a non-privileged user and group ID, making it impossible to regain elevated access without restarting. This involves first setting the group ID with setgid(non_priv_gid), followed by setuid(non_priv_uid) to avoid lingering group privileges. Verification of the effective user ID post-drop confirms the change, and failure to do so should result in process termination.[26]
Best practices include creating a PID file in /var/run/ (or /run/ on modern systems) to record the daemon's process ID, enabling external management tools to track and signal it. The file should be written atomically, often using open() with O_CREAT | O_EXCL and appropriate permissions (e.g., 0644), with the directory owned by root to prevent tampering. For logging, daemons should direct output to the system logger via syslog(3) rather than files or console, using facilities like LOG_DAEMON and priorities such as LOG_INFO or LOG_ERR to categorize messages. The openlog() call initializes logging with an identifier (e.g., the daemon's name), ensuring messages are prefixed for easy identification in system logs.[3][27]
Lifecycle and Management
Daemons are typically initiated through various mechanisms to ensure they start at appropriate times and remain operational. Startup can be managed by init systems such as systemd, which handle service activation during boot or on demand based on configured units.[25] Alternatively, daemons may be launched periodically via cron jobs, which execute scheduled tasks defined in crontab files. For efficiency in resource usage, super-servers like inetd or xinetd can start daemons on-demand when specific network requests arrive, avoiding the need for continuously running processes. Once running, daemons are monitored using PID files, which record the process ID in a designated file (e.g., /run/daemon.pid) to facilitate identification and management, or through process lists obtained via commands like ps.[28] During runtime, daemons operate in an event-driven manner, often employing system calls such as select() or poll() to efficiently wait for input/output events on multiple file descriptors without busy-waiting, thereby conserving CPU resources. Effective resource management is crucial, including periodic checks and careful allocation to prevent issues like memory leaks, which can be detected using tools such as valgrind during development.[29] Health monitoring typically involves mechanisms like heartbeat signals, where daemons periodically send status updates to a central monitor to confirm operational status and detect failures promptly.[30] Shutdown processes prioritize graceful termination to allow proper cleanup. Init systems commonly send a SIGTERM signal to the daemon's main process, giving it an opportunity to handle the signal, close open files, release locks, and perform other necessary cleanup before exiting.[25] If the daemon does not respond within a timeout period, a SIGKILL signal is issued to forcibly terminate it, though this bypasses cleanup and should be used sparingly.[25] These signal-based controls ensure orderly resource deallocation, minimizing system disruption. Logging is integral to daemon operation for recording events, errors, and diagnostics. Daemons traditionally integrate with syslog for standardized message routing to local or remote logs, facilitating centralized collection and analysis.[8] In modern systems using systemd, integration with journald provides structured, binary logging that supports querying and rotation without relying on text files.[31] For debugging, tools like strace trace system calls and signals in real-time, revealing interactions with the kernel and potential issues without modifying the daemon code.[32] Security in daemon management emphasizes least privilege and isolation. Daemons should run as non-root users to limit potential damage from exploits, configurable via options like User= in systemd units.[33] Sandboxing techniques, such as those provided by systemd's ProtectSystem= or PrivateTmp=, restrict access to the filesystem and temporary directories, containing breaches.[34] Additionally, auditing via the Linux Audit system logs security-relevant events like process execution and file accesses, enabling vulnerability detection and compliance verification.[35]Platform-Specific Implementations
Unix-like Systems
In Unix-like systems, the init process plays a central role in managing daemons as the parent of all processes, typically running with process ID 1 (PID 1). Traditional System V (SysV) init relies on runlevel-based scripts located in directories like /etc/init.d to start daemons during boot, sequencing services based on dependencies defined in those scripts. Upstart, an event-driven successor used in earlier Ubuntu versions, improved upon SysV by triggering daemon launches in response to system events rather than strict runlevels. Modern Linux distributions, however, predominantly employ systemd as the init system, where PID 1 is the systemd process itself; it starts daemons via declarative unit files (e.g., .service files) and supports boot-time activation through parallel processing for faster initialization, as well as socket activation to defer daemon startup until a connection is requested.[36][37] Historically, super-servers like inetd provided on-demand spawning of daemons for network services in Unix systems from the 1980s onward, listening on multiple ports and forking child processes only when incoming connections arrived to conserve resources. xinetd later enhanced inetd with features like access controls and logging, serving as a more secure drop-in replacement during the 1990s. In contemporary Unix-like environments, particularly those using systemd, socket units have supplanted these super-servers; systemd listens on sockets defined in .socket files and activates associated services dynamically upon activity, offering tighter integration with the init system and improved performance without the need for separate daemons like xinetd.[38][39] Daemon configuration in Unix-like systems commonly occurs through files in the /etc/ directory, allowing administrators to customize behavior without recompiling software; for instance, the SSH daemon uses /etc/ssh/sshd_config to specify settings like port numbers, authentication methods, and key locations. Management of running daemons varies by init system but emphasizes standardized tools: in systemd environments, the systemctl utility handles operations such as starting a service withsystemctl start <service>, stopping it with systemctl stop <service>, reloading configurations via systemctl reload <service> (often triggered by SIGHUP), and querying status with systemctl status <service>, which displays logs and resource usage. Representative examples include the cron daemon, which runs continuously to parse crontab files and execute scheduled tasks at predefined intervals, and the udev daemon (systemd-udevd in modern setups), which monitors kernel uevents to dynamically create device nodes, apply rules for hotplug events, and notify other services of hardware changes.[40][41][42]
On macOS, a Unix-like variant, launchd serves as the init and service management system for both system-wide and per-user daemons since its introduction in 2005 with Mac OS X 10.4 Tiger, replacing legacy mechanisms like classic control panels and extensions with a unified plist-based framework that supports on-demand loading, dependency resolution, and resource limits defined in XML property list files under /Library/LaunchDaemons or ~/Library/LaunchAgents. Unix-like daemons must comply with POSIX standards for signal handling and process groups to ensure reliable operation; for example, daemons typically create new sessions with setsid() to detach from controlling terminals, join process groups for coordinated signaling (e.g., via killpg() to broadcast SIGTERM), and handle standard signals like SIGTERM for graceful shutdowns or SIGHUP for configuration reloads without interrupting service.[43]
Windows Systems
In Windows systems, daemons are implemented as services, which are long-running background processes managed by the operating system to perform system-level tasks without user interaction. This architecture was introduced with Windows NT 3.1 in 1993, providing a structured way to handle server-like functionality on client and server editions alike.[44][15] Services operate under the control of the Service Control Manager (SCM), a component of the Windows executive that oversees service installation, startup, configuration, and termination. The SCM communicates with services via remote procedure calls (RPC) and maintains a database of service entries, ensuring they run with appropriate privileges, often under the LocalSystem account or other restricted contexts.[45][46] Services are categorized by startup types defined in the registry: automatic (starts at boot without user logon), manual (starts on demand), and disabled (prevented from starting). The SCM enforces these types during system initialization, loading services in dependency order to avoid conflicts— for instance, a service dependent on networking will wait for the network stack to initialize. Configuration details, including startup type, dependencies, and recovery actions, are stored in registry keys underHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services, where each service has a subkey containing values like Start (for startup type), DependOnService (for dependencies), and FailureActions (for recovery). Recovery options allow administrators to specify actions on failure, such as restarting the service after a delay, running a custom program, or logging to the event log, enhancing reliability for critical processes.[47][48][49]
To create a service, developers or administrators use the SCM API functions such as StartService (to initiate a service) and ControlService (to send control codes for start, stop, pause, or query status), which interact directly with the SCM database. Command-line tools like sc.exe provide equivalent functionality for installation and management, for example, sc create to add a new service entry. In modern environments, PowerShell's New-Service cmdlet simplifies creation by specifying the service name, executable path, and startup type, automatically updating the registry and SCM.[50][51][52]
Management interfaces include the Services console (services.msc), a Microsoft Management Console (MMC) snap-in that allows graphical viewing, starting, stopping, and property editing of services, with options to set dependencies and recovery behaviors. Services integrate with the Windows Event Viewer for logging, where they write operational events, errors, and diagnostics to channels like the System or Application logs, enabling troubleshooting via event IDs and timestamps.[53][54]
Representative examples include the Print Spooler service (Spooler), which manages print jobs by queuing, routing, and processing them to local or network printers, and the Remote Procedure Call service (RpcSs), which acts as the endpoint mapper for RPC communications, registering and locating server endpoints for distributed applications while managing COM and DCOM object activations. Prior to Windows Vista, services could be configured as interactive, allowing them to display user interface elements on the desktop for tasks like setup wizards; however, starting with Vista, such interactions were restricted to enhance security by isolating services from user sessions.[55][56][57]
Legacy Systems
In the 1980s, MS-DOS utilized terminate-and-stay-resident (TSR) programs as the primary mechanism for daemon-like background functionality in its single-tasking environment. These programs were loaded during system boot via entries in the CONFIG.SYS file for device drivers or the AUTOEXEC.BAT file for executable TSRs, allowing them to remain in memory and provide ongoing services such as input handling or network support without terminating. For instance, the Microsoft Network Client for MS-DOS employed TSR implementations for protocols like NETBEUI to enable peer-to-peer networking over local area networks, facilitating file and printer sharing among machines. However, MS-DOS's lack of true multitasking meant TSRs relied on cooperative hooks into interrupt vectors, often resulting in memory conflicts, stack overflows, and system instability when multiple programs competed for resources.[58][59][60] Classic Mac OS, spanning from 1984 to 2001 before the transition to OS X, implemented background processes through extensions and control panels, which were code modules loaded into the system heap at startup to augment the cooperative multitasking kernel. Extensions, typically with .init file extensions, executed initialization code to patch the Toolbox and provide persistent services like device management or protocol handling, while control panels (CDEVs) offered user-configurable background tasks via desk accessories. A key example was AppleTalk, Apple's proprietary networking suite, which operated as both an extension for low-level protocol support and a control panel for configuration, enabling file sharing and printer access over LocalTalk or EtherTalk networks in a resource-constrained environment. Management of these components was facilitated by the Extensions Manager starting with System 7.5 in 1994, which allowed selective enabling or disabling to mitigate crashes from incompatible code segments.[61][62] Other legacy systems featured analogous constructs for persistent background execution. In IBM's z/OS, started tasks function as daemon equivalents, consisting of Job Control Language (JCL) statements stored in libraries like SYS1.PROCLIB and initiated via the START operator command to run indefinitely for system monitoring, data processing, or subsystem support. The OpenVMS operating system, originating in the mid-1970s from Digital Equipment Corporation, used detached processes—created via the RUN/DETACHED command or JOB_CONTROL routines—to execute independently as batch jobs or servers, often without interactive terminals and with quotas governed by system parameters like PQL_M*.[63][64] These legacy approaches laid foundational concepts for modern daemons, particularly the notion of boot-time loading and persistent residency seen in TSR programs, which influenced early Windows architectures. In Windows 3.x and 9x, TSR-like virtual device drivers (VxDs) extended the MS-DOS base to handle background tasks in protected mode, bridging toward the service model in Windows NT where processes run detached from user sessions under the Service Control Manager.[24]Modern Contexts
Cloud and Distributed Systems
In cloud computing environments, daemons play a crucial role in enabling scalable infrastructure services such as monitoring, load balancing, and auto-scaling. For instance, the AWS CloudWatch agent operates as a daemon on EC2 instances and other hosts to collect metrics, logs, and traces, facilitating real-time observability across distributed systems.[65] Similarly, HAProxy functions as a background daemon process for high-performance load balancing, distributing traffic across backend servers in cloud deployments like those on AWS or Google Cloud, ensuring efficient resource utilization.[66] Auto-scaling mechanisms often rely on daemon-based agents, such as the Nomad Autoscaler, which runs as a persistent process to monitor workload demands and dynamically adjust cluster capacity in response to traffic variations.[67] These daemons are frequently containerized and deployed on virtual machines in platforms like AWS EC2 or Azure VMs to support elastic scaling without manual intervention.[68] Distributed daemons extend this functionality across multiple nodes, coordinating through tools like etcd and Consul for service discovery and configuration management. Etcd, a distributed key-value store, runs as a daemon cluster to provide consistent coordination, enabling daemons to register services and detect failures in real-time environments. Consul similarly operates as a daemon-based service for dynamic service discovery, allowing daemons to query and connect to peers in a mesh network, which is essential for maintaining connectivity in large-scale cloud setups. A prominent example is the Kubernetes kubelet, introduced in 2014 as the primary node agent daemon, which manages pod lifecycles, ensures container execution, and communicates with the cluster API server to handle distributed workloads.[69] Key challenges in deploying daemons within cloud and distributed systems include achieving high availability through failover clustering, where redundant daemon instances automatically take over during node failures to minimize downtime, as implemented in Red Hat's High Availability Add-On for clustered services.[70] Security in multi-tenant clouds demands strict enforcement, such as SELinux policies that confine daemon privileges to prevent lateral movement between tenants, thereby isolating processes in shared environments.[71] Additionally, logging poses scalability issues, addressed by forwarding daemon outputs to centralized systems like the ELK Stack (Elasticsearch, Logstash, Kibana), where agents such as Filebeat run as daemons to aggregate and index logs from distributed nodes for analysis. The evolution of daemons reflects a shift from monolithic designs to microservices-oriented architectures, where lightweight, service-specific daemons handle isolated functions within containerized ecosystems, improving modularity and fault isolation.[72] In serverless paradigms, such as AWS Lambda, the need for traditional always-on daemons diminishes, as event-driven functions replace persistent processes, reducing operational overhead while maintaining scalability through managed execution environments. This transition emphasizes ephemeral, on-demand computation over long-running background services.Containers and Orchestration
In containerized environments, the Docker daemon, known as dockerd, serves as the core persistent process responsible for managing Docker objects such as containers, images, networks, and volumes. Introduced in 2013 as part of the initial Docker Engine release, dockerd persists data in a configurable directory like/var/lib/docker on Linux systems and exposes a RESTful API for interaction, typically via Unix domain sockets for local access or TCP ports (e.g., tcp://192.168.59.3:2376) for remote connections, enabling orchestration tools to control container lifecycles.[73][74]
Kubernetes, a prominent container orchestration platform, relies on several components that operate as daemons to manage cluster resources and runtime operations. The kube-apiserver daemon exposes the Kubernetes API for all administrative tasks, while the kube-scheduler daemon assigns pods to nodes based on resource availability and policies. On worker nodes, the kubelet daemon ensures that pods and their containers are running and healthy, interfacing with container runtimes like containerd, which itself functions as a daemon to handle low-level container execution, image pulling, and storage management. These daemons collectively enable scalable orchestration, with kubelet and containerd providing node-level runtime control.[75][76]
Alternatives to traditional daemon-based runtimes address limitations in security and complexity within orchestration workflows. Podman offers a daemonless container engine that emulates Docker's CLI and compatibility, allowing rootless operation without a central privileged process, and integrates with Kubernetes through tools like CRI-O for pod management and YAML deployment. CRI-O, a lightweight, Kubernetes-specific implementation of the Container Runtime Interface (CRI), runs as a dedicated daemon focused solely on CRI compliance, pulling images and starting containers while delegating broader management to Kubernetes components; this design tackles orchestration challenges such as daemon health monitoring via liveness probes and facilitating rolling updates without the overhead of full-featured runtimes like Docker.[77]
Security in these daemon-driven container environments hinges on Linux kernel features for isolation, including namespaces—which segregate process IDs, network stacks, and mount points—and control groups (cgroups), which limit resource usage to prevent denial-of-service attacks. However, daemons like dockerd have been vulnerable to exploits; for instance, in 2019, CVE-2019-5736 in the underlying runc library allowed container escapes to gain host root access by overwriting runc binaries, affecting default Docker setups and highlighting risks when daemons run with elevated privileges.[78][79]
As of 2025, trends in container daemons emphasize eBPF (extended Berkeley Packet Filter) for kernel-level enhancements, enabling efficient observability, networking, and security without heavy user-space daemons; for example, eBPF programs in tools like Cilium provide significant performance improvements compared to iptables, shifting more logic to the kernel for faster policy enforcement and lower latency in orchestrated environments.[80][81] In 2025, major platforms like AWS EKS have adopted Cilium with eBPF as a default networking option, further integrating these technologies into managed services.[82]References
- https://wiki.gentoo.org/wiki/Comparison_of_init_systems/en