In the world of Linux, services (background processes) are the backbone of system functionality, handling everything from network management to user authentication. Managing these services—starting, stopping, enabling at boot, or troubleshooting—relies on a critical component: the init system. The init system is the first process launched by the kernel (with PID 1) and is responsible for initializing the system, spawning other processes, and managing service lifecycles. For decades, SysVinit (or simply init) was the dominant init system, known for its simplicity and reliance on shell scripts. However, as Linux systems grew more complex, a need arose for a more robust, feature-rich alternative. Enter systemd—a modern init system designed to address the limitations of SysVinit with parallelization, on-demand activation, and integrated logging. This blog explores the fundamental concepts, usage methods, and best practices for managing Linux services with both SysVinit and systemd. Whether you’re maintaining legacy systems or adopting modern Linux distributions, understanding these tools is essential for effective system administration.
Table of Contents
- Understanding Linux Services and Init Systems
- What is Init (SysVinit)?
- What is Systemd?
- Systemd vs. Init: Key Differences
- Usage Methods: Init
- Usage Methods: Systemd
- Common Practices
- Best Practices
- Conclusion
- References
Understanding Linux Services and Init Systems
What Are Linux Services?
A service is a background process that runs independently of user sessions, providing core functionality like web servers (nginx), databases (mysql), or network services (sshd). Services are typically started at boot and run continuously, though they can also be manually controlled by administrators.
The Role of the Init System
The init system is the “mother of all processes” (PID 1). Its primary responsibilities include:
- Initializing the system after boot (e.g., mounting filesystems, starting network services).
- Managing service lifecycles (starting, stopping, restarting services).
- Handling runlevels (or “targets” in systemd) to define system states (e.g., multi-user mode, graphical mode).
- Reaping orphaned processes to prevent resource leaks.
Two init systems have dominated Linux: SysVinit (traditional) and systemd (modern). Let’s dive into each.
What is Init (SysVinit)?
Overview
SysVinit (System V Init) traces its roots to Unix System V and was the default init system for most Linux distributions until the 2010s. It is simple, lightweight, and relies on shell scripts to manage services and runlevels.
Core Concepts:
- Runlevels: Predefined system states (0-6) that determine which services start. For example:
0: Halt1/S: Single-user mode (no networking, minimal services)3: Multi-user mode (text-only, no GUI)5: Graphical multi-user mode (with GUI)6: Reboot.
- Init Scripts: Services are managed via shell scripts stored in
/etc/init.d/. These scripts define how to start, stop, or restart a service and include metadata (e.g., dependencies, runlevels). - Sequential Startup: Services start one after another in a fixed order, based on dependencies defined in init scripts.
Example Init Script
A basic init script for a hypothetical service (myservice) might look like this:
#!/bin/bash
### BEGIN INIT INFO
# Provides: myservice
# Required-Start: $network $local_fs
# Required-Stop: $network $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My custom background service
### END INIT INFO
case "$1" in
start)
echo "Starting myservice..."
/usr/bin/myservice --daemon
;;
stop)
echo "Stopping myservice..."
pkill -f /usr/bin/myservice
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
This script includes LSB (Linux Standard Base) headers (between ### BEGIN/END INIT INFO ###) to define dependencies and default runlevels, ensuring compatibility with tools like chkconfig.
What is Systemd?
Overview
Introduced in 2010, systemd (system daemon) was designed to modernize Linux initialization. It replaces SysVinit with a suite of tools for service management, logging, and system configuration. Key features include parallel service startup, on-demand activation, and tight integration with kernel cgroups for resource management.
Core Concepts:
- Units: Systemd’s fundamental building blocks, representing services, sockets, devices, or targets. Service units (
.servicefiles) replace init scripts. - Targets: Replace runlevels, defining system states (e.g.,
multi-user.targetfor text mode,graphical.targetfor GUI). - Parallel Startup: Services start concurrently (where dependencies allow), reducing boot time.
- Journald: Integrated logging daemon (
journalctl) for centralized, structured log management. - On-Demand Activation: Services start only when needed (e.g., via socket activation for rarely used services).
Example Service Unit File
A systemd service unit file (/etc/systemd/system/myservice.service) for the same hypothetical service:
[Unit]
Description=My custom background service
After=network.target local-fs.target # Start after these targets
[Service]
Type=simple # Process runs in foreground (systemd monitors it)
ExecStart=/usr/bin/myservice --daemon # Command to start the service
Restart=on-failure # Restart if the service fails
User=www-data # Run as non-root user
WorkingDirectory=/opt/myservice
[Install]
WantedBy=multi-user.target # Enable when multi-user.target is active
Unit files are declarative and structured into sections ([Unit], [Service], [Install]), making them easier to read and maintain than shell scripts.
Systemd vs. Init: Key Differences
| Feature | SysVinit (Init) | Systemd |
|---|---|---|
| Startup Model | Sequential (one service at a time) | Parallel (concurrent where possible) |
| Service Definition | Shell scripts in /etc/init.d/ | Unit files (.service, .target, etc.) |
| Runlevels | Fixed runlevels (0-6) | Targets (e.g., multi-user.target) |
| Logging | Relies on syslog (text files in /var/log) | journald (binary logs, queryable via journalctl) |
| Dependency Management | Manual (via init script ordering) | Automatic (via After=/Requires= in units) |
| On-Demand Activation | Not supported | Native (via sockets, timers, or D-Bus) |
| Resource Management | Limited (no built-in cgroup support) | Integrated cgroup support (CPU/memory limits) |
| Service Monitoring | Basic (pidfiles) | Advanced (process tracking, restart policies) |
Usage Methods: Init
Core Commands for SysVinit
SysVinit relies on two primary tools for service management: service (a wrapper for init scripts) and chkconfig (for enabling/disabling services at boot).
1. Starting/Stopping/Restarting Services
Use service <service> <action> or directly execute the init script:
# Start a service
sudo service myservice start
# Or
sudo /etc/init.d/myservice start
# Stop a service
sudo service myservice stop
# Restart a service
sudo service myservice restart
# Check status (varies by script)
sudo service myservice status
2. Enabling/Disabling Services at Boot
Use chkconfig (Red Hat-based) or update-rc.d (Debian-based) to manage persistent service activation:
# Red Hat/CentOS: List all services and runlevels
chkconfig --list
# Enable myservice at runlevels 2,3,4,5
chkconfig myservice on
# Disable myservice at boot
chkconfig myservice off
# Debian/Ubuntu: Add myservice to boot sequence
sudo update-rc.d myservice defaults
# Remove myservice from boot sequence
sudo update-rc.d myservice remove
3. Managing Runlevels
View or change the current runlevel with runlevel and telinit:
# Check current runlevel
runlevel # Output: N 3 (N=previous runlevel, 3=current)
# Switch to graphical runlevel (5)
sudo telinit 5
Usage Methods: Systemd
Systemd centralizes service management with systemctl (system control) and logging with journalctl.
Core systemctl Commands
1. Starting/Stopping/Restarting Services
# Start a service immediately
sudo systemctl start myservice.service # .service suffix is optional
# Stop a service
sudo systemctl stop myservice
# Restart a service (stop + start)
sudo systemctl restart myservice
# Reload configuration without stopping (if supported)
sudo systemctl reload myservice
2. Enabling/Disabling Services at Boot
enable/disable persists across reboots by creating/deleting symlinks in target directories:
# Enable myservice to start at boot
sudo systemctl enable myservice
# Disable myservice (no longer starts at boot)
sudo systemctl disable myservice
# Check if a service is enabled
systemctl is-enabled myservice # Output: enabled/disabled/masked
# Temporarily start a service (not persistent)
sudo systemctl start myservice # Use enable for persistence
3. Checking Service Status
# Detailed status of a service
systemctl status myservice
# Output includes: active state, PID, logs, and dependencies
# Check if a service is active (running)
systemctl is-active myservice # Output: active/inactive/failed
4. Managing Targets (Runlevels)
Targets group services into logical states. Use these commands to manage system modes:
# List all targets
systemctl list-targets
# Check default target (boot target)
systemctl get-default # Output: multi-user.target
# Set default target to graphical mode
sudo systemctl set-default graphical.target
# Switch to emergency mode (single-user, minimal services)
sudo systemctl isolate emergency.target
5. Logging with journalctl
Systemd’s journald aggregates logs from services, the kernel, and users. Use journalctl to query them:
# View logs for myservice
journalctl -u myservice.service
# Follow real-time logs (like tail -f)
journalctl -u myservice -f
# Filter logs by time (e.g., last hour)
journalctl -u myservice --since "1 hour ago"
# View kernel logs
journalctl -k
6. Reloading Systemd Configuration
After editing a unit file, reload systemd to apply changes:
sudo systemctl daemon-reload
Creating Custom Service Units
To add a custom service, create a .service file in /etc/systemd/system/ (system-wide) or ~/.config/systemd/user/ (user-specific). After creating/editing, run sudo systemctl daemon-reload to reload.
Common Practices
For SysVinit:
- Write Compliant Init Scripts: Include LSB headers (e.g.,
Required-Start,Default-Start) for compatibility withchkconfig/update-rc.d. - Test Scripts: Validate init scripts with
bash -n /etc/init.d/myserviceto catch syntax errors. - Use
serviceOver Direct Script Execution:serviceensures consistent environment variables and error handling.
For Systemd:
- Leverage Targets: Use
WantedBy=multi-user.targetfor most services (runs in text mode) orgraphical.targetfor GUI-dependent services. - Mask Services: Temporarily or permanently prevent a service from starting with
systemctl mask myservice(blocks even manual starts). - Edit Units Safely: Use
systemctl edit myserviceto create an override file (avoids modifying the original unit file).
Best Practices
General Best Practices
- Test Changes: Always test service start/stop/restart commands before relying on them in production.
- Monitor Services: Use tools like
monit(SysVinit) orsystemctl status/journalctl(systemd) to track service health. - Document Changes: Log service configuration edits (e.g., modified unit files or init scripts) for troubleshooting.
Systemd-Specific Best Practices
- Run Services as Non-Root: Use
User=andGroup=in.servicefiles to limit privileges. - Set Restart Policies: Use
Restart=on-failureto automatically recover from crashes (avoids manual intervention). - Limit Resources: Use cgroup properties (e.g.,
CPUQuota=50%,MemoryLimit=1G) in the[Service]section to prevent resource exhaustion. - Avoid Overcomplicating Units: Keep unit files simple; split complex logic into helper scripts if needed.
SysVinit-Specific Best Practices
- Idempotent Scripts: Ensure init scripts handle cases where the service is already started/stopped (e.g., “stop” does nothing if not running).
- Log to Syslog: Use
loggerin init scripts to send output tosyslog(e.g.,logger "myservice stopped"). - Handle Dependencies Manually: Explicitly check for required services (e.g.,
if ! service network status >/dev/null; then exit 1; fi).
Conclusion
The shift from SysVinit to systemd marks a significant evolution in Linux service management. While SysVinit excels in simplicity and compatibility with legacy systems, systemd’s parallel startup, integrated logging, and dependency management make it better suited for modern, complex Linux environments.
Today, most major distributions (Ubuntu, Fedora, Debian, RHEL) use systemd, but understanding SysVinit remains valuable for maintaining older systems or lightweight distributions (e.g., Devuan, which retains SysVinit). By mastering both systems’ tools—service/chkconfig for init and systemctl/journalctl for systemd—you’ll be equipped to manage services effectively across any Linux environment.
References
- Systemd Official Documentation
- SysVinit Manual (Linux Foundation)
- systemctl(1) Man Page
- journalctl(1) Man Page
- Debian Init Scripts Guide
- Red Hat System Administrator’s Guide: Services and Daemons
This blog provides a foundation for managing Linux services with init and systemd. For deeper dives, explore the referenced documentation or experiment with unit file customization and advanced journalctl queries!