Init Systems
Overview
Init systems have evolved significantly:
# Historical progression:
# SysVinit (System V) - Traditional init system
# Upstart - Ubuntu replacement for SysVinit
# systemd - Modern init system (most Linux distributions)
# Check which init system is running
ps aux | grep -E "^\s*1\s" | grep -v grep
# Output shows: /sbin/init or /lib/systemd/systemd
# Alternative check
systemctl --version # If systemd
# or
initctl --version # If Upstart
SysVinit (Traditional)
Service Management
# Check if SysVinit is in use
ls -la /etc/init.d/
# List available services
ls /etc/init.d/
# Start service
sudo /etc/init.d/apache2 start
sudo service apache2 start
# Stop service
sudo /etc/init.d/apache2 stop
sudo service apache2 stop
# Restart service
sudo /etc/init.d/apache2 restart
sudo service apache2 restart
# Reload service (graceful)
sudo /etc/init.d/apache2 reload
sudo service apache2 reload
# Get service status
sudo /etc/init.d/apache2 status
sudo service apache2 status
Runlevels
# SysVinit uses runlevels 0-6:
# 0 - Halt
# 1 - Single user (maintenance mode)
# 2 - Multi-user, no networking (Debian default)
# 3 - Multi-user with networking (Red Hat default)
# 4 - Unused (customizable)
# 5 - Multi-user with GUI
# 6 - Reboot
# Check current runlevel
runlevel
# Set default runlevel (edit /etc/inittab)
# Look for line: id:3:initdefault:
# Change runlevel temporarily
sudo init 3 # Switch to runlevel 3
sudo init 5 # Switch to runlevel 5
# View /etc/inittab
cat /etc/inittab
Managing Services at Boot
# Update-rc.d (Debian/Ubuntu)
sudo update-rc.d apache2 enable # Enable at boot
sudo update-rc.d apache2 disable # Disable at boot
sudo update-rc.d apache2 remove # Remove service links
# chkconfig (Red Hat/CentOS)
sudo chkconfig apache2 on # Enable at boot
sudo chkconfig apache2 off # Disable at boot
sudo chkconfig --list apache2 # List current status
# Check if service starts on boot
ls /etc/rc3.d/ | grep apache2
# S = start, K = kill (stop)
# Format: S99apache2 (start at position 99)
Systemd (Modern Init System)
Systemd is the default init system on most modern Linux distributions.
Service Management
# Check if systemd is in use
systemctl --version
# Start service
sudo systemctl start apache2
sudo systemctl start mysql
# Stop service
sudo systemctl stop apache2
sudo systemctl stop mysql
# Restart service
sudo systemctl restart apache2
sudo systemctl restart mysql
# Reload service (graceful, no downtime)
sudo systemctl reload apache2
sudo systemctl reload nginx
# Get service status
sudo systemctl status apache2
# Shows: running, stopped, failed, etc.
# View service details
sudo systemctl show apache2
Service Management at Boot
# Enable service to start at boot
sudo systemctl enable apache2
# Disable service from starting at boot
sudo systemctl disable apache2
# Check if service is enabled
sudo systemctl is-enabled apache2
# Mask service (prevent start even if enabled)
sudo systemctl mask apache2
# Unmask service
sudo systemctl unmask apache2
# Check enabled/disabled status
sudo systemctl list-unit-files --state=enabled
sudo systemctl list-unit-files --state=disabled
Targets (Runlevels equivalent)
# Systemd targets replace SysVinit runlevels:
# poweroff.target (runlevel 0)
# rescue.target (runlevel 1 - single user)
# multi-user.target (runlevel 3 - multi-user, no GUI)
# graphical.target (runlevel 5 - multi-user with GUI)
# reboot.target (runlevel 6)
# Check current target
systemctl get-default
# Set default target
sudo systemctl set-default multi-user.target
sudo systemctl set-default graphical.target
# Switch to target temporarily
sudo systemctl isolate multi-user.target
sudo systemctl isolate rescue.target
# List all available targets
systemctl list-unit-files --type=target
Unit Files
# Systemd unit files location:
# /lib/systemd/system/ - Package-provided units
# /etc/systemd/system/ - Administrator units
# ~/.config/systemd/user/ - User units
# Find a service unit file
systemctl cat apache2
# Shows full path and contents
# Edit service unit file
sudo systemctl edit apache2
# Opens in default editor (creates override in /etc/systemd/system/)
# Reload unit file changes
sudo systemctl daemon-reload
sudo systemctl restart apache2
# Example unit file structure:
# [Unit]
# Description=Apache HTTP Server
# After=network.target
#
# [Service]
# Type=notify
# ExecStart=/usr/sbin/apache2ctl start
# ExecStop=/usr/sbin/apache2ctl stop
# Restart=on-failure
#
# [Install]
# WantedBy=multi-user.target
Monitoring and Logs
# View systemd journal logs
journalctl
# View logs for specific service
sudo journalctl -u apache2
# View last N lines
sudo journalctl -u apache2 -n 50
# Follow logs in real-time (like tail -f)
sudo journalctl -u apache2 -f
# Show logs since last boot
sudo journalctl -b
# Show logs from specific time range
sudo journalctl --since "2024-01-15 10:00:00" --until "2024-01-15 11:00:00"
# Filter by priority level
sudo journalctl -p err # Errors only
sudo journalctl -p warning # Warnings and above
# Show available services and their status
systemctl list-units --type=service
systemctl list-units --type=service --state=running
systemctl list-units --type=service --state=failed
# Check for failed units
systemctl --failed
Timers (Cron Replacement)
# Systemd can replace cron for scheduled tasks
# List all timers
systemctl list-timers
# Create a timer unit in /etc/systemd/system/
# Example: backup.timer
# View timer status
sudo systemctl status backup.timer
# Enable timer
sudo systemctl enable backup.timer
# Start timer
sudo systemctl start backup.timer
# Check timer details
sudo systemctl cat backup.timer
Comparison Table
| Operation | SysVinit | Upstart | Systemd |
|---|---|---|---|
| Start service | service nginx start | start nginx | systemctl start nginx |
| Stop service | service nginx stop | stop nginx | systemctl stop nginx |
| Restart service | service nginx restart | restart nginx | systemctl restart nginx |
| Enable at boot | chkconfig nginx on | initctl nginx enable | systemctl enable nginx |
| Disable at boot | chkconfig nginx off | initctl nginx disable | systemctl disable nginx |
| Check status | service nginx status | status nginx | systemctl status nginx |
| View logs | tail /var/log/syslog | tail /var/log/syslog | journalctl -u nginx |
| Manage runlevels | init 3 | N/A | systemctl isolate multi-user.target |
Common Troubleshooting
# Service fails to start
sudo systemctl status apache2
# Check "Active" line for error details
# View detailed error messages
sudo journalctl -u apache2 -n 100
# Service stuck in failed state
sudo systemctl reset-failed apache2
# Check if service file has syntax errors
sudo systemd-analyze verify apache2.service
# Debug service startup
sudo systemctl start apache2 -v
# Or check journal: journalctl -u apache2 -e
# Port already in use
sudo lsof -i :80
# Kill process if needed: sudo kill -9 <PID>
# Permission denied errors
# Check service unit file for User= directive
sudo systemctl cat apache2 | grep User=
# Service dependency issues
# View unit dependencies
sudo systemctl list-dependencies apache2
# Deadlock or circular dependencies
sudo systemd-analyze
# Shows dependency graph
Best Practices
- Use systemctl instead of service commands (systemd standard)
- Enable services explicitly:
systemctl enable service-name - Monitor service status regularly:
systemctl list-units --failed - Check logs immediately after service restart:
journalctl -u service-name -f - Use
systemctl reloadinstead of restart when possible (no service interruption) - Keep service unit files in
/etc/systemd/system/for modifications - Use
systemctl daemon-reloadafter editing unit files - Set up automated restarts for critical services
- Monitor journal size:
journalctl --disk-usage - Archive old logs:
sudo journalctl --vacuum=30d(keep 30 days)
Resources
Last updated: 2026-03-30