How to understand runlevels and targets
How to Understand Runlevels and Targets
Table of Contents
1. [Introduction](#introduction)
2. [Prerequisites](#prerequisites)
3. [Understanding System Initialization](#understanding-system-initialization)
4. [Traditional SysV Runlevels](#traditional-sysv-runlevels)
5. [Modern Systemd Targets](#modern-systemd-targets)
6. [Practical Examples and Commands](#practical-examples-and-commands)
7. [Managing Services and Dependencies](#managing-services-and-dependencies)
8. [Troubleshooting Common Issues](#troubleshooting-common-issues)
9. [Best Practices and Professional Tips](#best-practices-and-professional-tips)
10. [Migration from Runlevels to Targets](#migration-from-runlevels-to-targets)
11. [Conclusion](#conclusion)
Introduction
Understanding runlevels and targets is fundamental for Linux system administrators and power users who need to manage system initialization, service startup, and system states effectively. This comprehensive guide will take you through the evolution from traditional SysV runlevels to modern systemd targets, providing you with the knowledge and practical skills needed to manage Linux systems confidently.
Runlevels and targets define different operational states of a Linux system, determining which services run and how the system behaves. While older Linux distributions relied on SysV init systems with numbered runlevels, modern distributions have largely adopted systemd with its more flexible target-based approach.
By the end of this article, you will understand how to navigate both systems, manage services effectively, troubleshoot initialization problems, and implement best practices for system administration.
Prerequisites
Before diving into runlevels and targets, ensure you have:
- Basic Linux Knowledge: Familiarity with command-line interface and basic Linux commands
- Root Access: Administrative privileges on a Linux system for testing commands
- Text Editor Skills: Ability to use text editors like vim, nano, or emacs
- System Access: Access to a Linux system (physical, virtual machine, or container)
- Understanding of Services: Basic knowledge of what system services are and their purpose
Recommended Tools
- Terminal emulator or SSH client
- Text editor (vim, nano, or gedit)
- System with both SysV and systemd examples (optional but helpful)
Understanding System Initialization
The Boot Process Overview
When a Linux system boots, it follows a specific sequence:
1. BIOS/UEFI: Hardware initialization and bootloader selection
2. Bootloader: GRUB loads the kernel and initial RAM disk
3. Kernel: Hardware detection and core system initialization
4. Init System: First user-space process (PID 1) that manages system initialization
5. Services: Starting system services based on the target runlevel or target
Init Systems Evolution
Linux has evolved through several init systems:
```bash
Traditional SysV Init (still used in some distributions)
/sbin/init
Upstart (used in older Ubuntu versions)
/sbin/upstart
Systemd (modern standard)
/lib/systemd/systemd
```
You can check which init system your system uses:
```bash
Check the init system
ps -p 1 -o comm=
Check systemd version (if applicable)
systemctl --version
Check if SysV compatibility is available
ls -la /etc/rc*.d/
```
Traditional SysV Runlevels
Understanding Runlevels
SysV runlevels are predefined system states, each serving specific purposes:
| Runlevel | Description | Typical Use |
|----------|-------------|-------------|
| 0 | Halt/Shutdown | System shutdown |
| 1 | Single-user mode | Emergency maintenance, password recovery |
| 2 | Multi-user mode without networking | Local maintenance |
| 3 | Multi-user mode with networking | Server mode (no GUI) |
| 4 | Undefined | Custom configuration |
| 5 | Multi-user mode with GUI | Desktop environment |
| 6 | Reboot | System restart |
SysV Directory Structure
The SysV system organizes startup scripts in specific directories:
```bash
Main runlevel directories
/etc/rc0.d/ # Shutdown scripts
/etc/rc1.d/ # Single-user mode scripts
/etc/rc2.d/ # Multi-user without network scripts
/etc/rc3.d/ # Multi-user with network scripts
/etc/rc4.d/ # Custom runlevel scripts
/etc/rc5.d/ # GUI mode scripts
/etc/rc6.d/ # Reboot scripts
Service scripts location
/etc/init.d/ # Actual service scripts
System configuration
/etc/inittab # Init configuration file
```
Working with SysV Runlevels
Checking Current Runlevel
```bash
Display current and previous runlevel
runlevel
Alternative method
who -r
```
Changing Runlevels
```bash
Change to runlevel 3 (multi-user, no GUI)
sudo init 3
Change to runlevel 5 (multi-user with GUI)
sudo init 5
Shutdown system (runlevel 0)
sudo init 0
Reboot system (runlevel 6)
sudo init 6
```
Managing Services in SysV
```bash
Start a service
sudo service apache2 start
Stop a service
sudo service apache2 stop
Restart a service
sudo service apache2 restart
Check service status
sudo service apache2 status
Enable service at boot
sudo chkconfig apache2 on
Disable service at boot
sudo chkconfig apache2 off
List all services and their runlevel status
chkconfig --list
```
SysV Script Structure
A typical SysV init script structure:
```bash
#!/bin/bash
/etc/init.d/myservice
MyService Custom service example
chkconfig: 35 99 99
description: Custom service for demonstration
. /etc/rc.d/init.d/functions
USER="myuser"
DAEMON="myservice"
ROOT_DIR="/var/lib/myservice"
SERVER="$ROOT_DIR/bin/myservice"
LOCK_FILE="/var/lock/subsys/myservice"
start() {
if [ -f $LOCK_FILE ]; then
echo "MyService is already running."
return 1
fi
echo -n "Starting $DAEMON: "
daemon --user="$USER" --pidfile="$LOCK_FILE" "$SERVER"
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
return $RETVAL
}
stop() {
if [ ! -f $LOCK_FILE ]; then
echo "MyService is not running."
return 1
fi
echo -n "Shutting down $DAEMON: "
pid=`ps -aefw | grep "$DAEMON" | grep -v " grep " | awk '{print $2}'`
kill -9 $pid > /dev/null 2>&1
[ $? -eq 0 ] && echo_success || echo_failure
echo
rm -f $LOCK_FILE
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
if [ -f $LOCK_FILE ]; then
echo "MyService is running."
else
echo "MyService is stopped."
fi
;;
restart)
stop
start
;;
*)
echo "Usage: {start|stop|status|restart}"
exit 1
;;
esac
exit $?
```
Modern Systemd Targets
Understanding Systemd Targets
Systemd targets are more flexible than traditional runlevels, allowing for:
- Parallel Service Startup: Services can start simultaneously
- Dependency Management: Sophisticated service dependencies
- On-Demand Activation: Services start only when needed
- Better Resource Management: More efficient system resource usage
Common Systemd Targets
| Target | Description | SysV Equivalent |
|--------|-------------|-----------------|
| poweroff.target | System shutdown | Runlevel 0 |
| rescue.target | Single-user rescue mode | Runlevel 1 |
| multi-user.target | Multi-user, no GUI | Runlevel 3 |
| graphical.target | Multi-user with GUI | Runlevel 5 |
| reboot.target | System restart | Runlevel 6 |
| emergency.target | Emergency shell | N/A |
Systemd Directory Structure
```bash
System unit files
/lib/systemd/system/ # Distribution-provided units
/etc/systemd/system/ # Local system administrator units
/run/systemd/system/ # Runtime units
User unit files
~/.config/systemd/user/ # User-specific units
/etc/systemd/user/ # System-wide user units
Configuration
/etc/systemd/system.conf # Main systemd configuration
```
Working with Systemd Targets
Checking Current Target
```bash
Show current target
systemctl get-default
List all active targets
systemctl list-units --type=target
Show current system state
systemctl status
```
Changing Targets
```bash
Change to multi-user target (no GUI)
sudo systemctl isolate multi-user.target
Change to graphical target (with GUI)
sudo systemctl isolate graphical.target
Set default target for next boot
sudo systemctl set-default multi-user.target
Emergency mode
sudo systemctl isolate emergency.target
Rescue mode
sudo systemctl isolate rescue.target
```
Managing Services with Systemd
```bash
Start a service
sudo systemctl start apache2
Stop a service
sudo systemctl stop apache2
Restart a service
sudo systemctl restart apache2
Reload service configuration
sudo systemctl reload apache2
Check service status
systemctl status apache2
Enable service at boot
sudo systemctl enable apache2
Disable service at boot
sudo systemctl disable apache2
Check if service is enabled
systemctl is-enabled apache2
List all services
systemctl list-units --type=service
List failed services
systemctl --failed
```
Practical Examples and Commands
Example 1: Creating a Custom Systemd Service
Create a custom systemd service file:
```bash
Create service file
sudo nano /etc/systemd/system/myapp.service
```
Service file content:
```ini
[Unit]
Description=My Custom Application
After=network.target
Wants=network.target
[Service]
Type=simple
User=myuser
Group=mygroup
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/myapp
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
Enable and start the service:
```bash
Reload systemd configuration
sudo systemctl daemon-reload
Enable the service
sudo systemctl enable myapp.service
Start the service
sudo systemctl start myapp.service
Check status
systemctl status myapp.service
```
Example 2: Creating a Custom Target
```bash
Create custom target
sudo nano /etc/systemd/system/maintenance.target
```
Target file content:
```ini
[Unit]
Description=Maintenance Mode
Requires=multi-user.target
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target
AllowIsolate=yes
[Install]
WantedBy=multi-user.target
```
Example 3: Service Dependencies
Create a service with complex dependencies:
```ini
[Unit]
Description=Web Application
After=network.target database.service
Requires=database.service
Wants=cache.service logging.service
[Service]
Type=notify
ExecStart=/usr/bin/webapp
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
```
Example 4: Timer-Based Service Activation
Create a timer for periodic service execution:
```bash
Create timer file
sudo nano /etc/systemd/system/backup.timer
```
Timer content:
```ini
[Unit]
Description=Daily Backup Timer
Requires=backup.service
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
```
Corresponding service file:
```ini
[Unit]
Description=Backup Service
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-script.sh
User=backup
```
Enable the timer:
```bash
sudo systemctl enable backup.timer
sudo systemctl start backup.timer
systemctl list-timers
```
Managing Services and Dependencies
Understanding Service Dependencies
Systemd provides several dependency types:
- Requires: Hard dependency - if dependency fails, service fails
- Wants: Soft dependency - service starts even if dependency fails
- After: Ordering dependency - start after specified units
- Before: Ordering dependency - start before specified units
- Conflicts: Negative dependency - cannot run simultaneously
Analyzing Dependencies
```bash
Show service dependencies
systemctl list-dependencies apache2
Show reverse dependencies
systemctl list-dependencies apache2 --reverse
Show dependency tree
systemctl list-dependencies --all
Analyze critical chain
systemd-analyze critical-chain
Show boot time analysis
systemd-analyze blame
```
Service States and Control
```bash
Show all service states
systemctl list-units --type=service --all
Show only active services
systemctl list-units --type=service --state=active
Show only failed services
systemctl list-units --type=service --state=failed
Mask a service (prevent it from starting)
sudo systemctl mask apache2
Unmask a service
sudo systemctl unmask apache2
```
Troubleshooting Common Issues
Boot Issues
Problem: System Won't Boot to Desired Target
Symptoms:
- System boots to wrong runlevel/target
- Services don't start as expected
- GUI doesn't load when expected
Solution:
```bash
Check default target
systemctl get-default
Set correct default target
sudo systemctl set-default graphical.target
Check for failed services
systemctl --failed
Analyze boot performance
systemd-analyze
systemd-analyze blame
```
Problem: Service Fails to Start
Symptoms:
- Service shows as failed in systemctl status
- Application not accessible
- Error messages in logs
Diagnostic Steps:
```bash
Check service status
systemctl status servicename
View service logs
journalctl -u servicename
View recent logs
journalctl -u servicename -n 50
Follow logs in real-time
journalctl -u servicename -f
Check service configuration
systemctl cat servicename
```
Common Solutions:
```bash
Reload systemd configuration
sudo systemctl daemon-reload
Reset failed services
sudo systemctl reset-failed
Edit service configuration
sudo systemctl edit servicename
Restart service
sudo systemctl restart servicename
```
Dependency Issues
Problem: Circular Dependencies
Detection:
```bash
Check for dependency loops
systemd-analyze verify servicename.service
Analyze critical chain
systemd-analyze critical-chain servicename.service
```
Resolution:
1. Review service dependencies in unit files
2. Remove unnecessary dependencies
3. Use `Wants` instead of `Requires` where appropriate
4. Implement proper ordering with `After` and `Before`
Problem: Service Timeout
Symptoms:
- Service takes too long to start
- Timeout errors in logs
Solution:
```bash
Increase timeout in service file
sudo systemctl edit servicename
```
Add timeout configuration:
```ini
[Service]
TimeoutStartSec=300
TimeoutStopSec=60
```
Performance Issues
Slow Boot Times
Analysis:
```bash
Overall boot time
systemd-analyze
Service-by-service breakdown
systemd-analyze blame
Critical path analysis
systemd-analyze critical-chain
Plot boot process
systemd-analyze plot > boot-analysis.svg
```
Optimization:
1. Disable unnecessary services
2. Optimize service dependencies
3. Use parallel service startup
4. Consider using socket activation
Log Analysis
Systemd Journal Commands
```bash
View all journal entries
journalctl
View entries for specific service
journalctl -u servicename
View entries since last boot
journalctl -b
View entries for specific time range
journalctl --since "2024-01-01" --until "2024-01-02"
View kernel messages
journalctl -k
View entries with specific priority
journalctl -p err
Follow logs in real-time
journalctl -f
Show disk usage
journalctl --disk-usage
Clean old logs
sudo journalctl --vacuum-time=7d
```
Best Practices and Professional Tips
Service Management Best Practices
1. Use Appropriate Service Types
```ini
For traditional daemons
[Service]
Type=forking
PIDFile=/var/run/myservice.pid
For modern applications
[Service]
Type=simple
ExecStart=/usr/bin/myapp
For one-shot scripts
[Service]
Type=oneshot
ExecStart=/usr/local/bin/setup-script.sh
```
2. Implement Proper Error Handling
```ini
[Service]
Type=simple
ExecStart=/usr/bin/myapp
Restart=on-failure
RestartSec=5
StartLimitInterval=60
StartLimitBurst=3
```
3. Use Security Features
```ini
[Service]
User=myappuser
Group=myappgroup
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/myapp
PrivateTmp=yes
```
4. Configure Resource Limits
```ini
[Service]
MemoryLimit=512M
CPUQuota=50%
TasksMax=100
```
System Administration Tips
1. Regular Monitoring
```bash
Create monitoring script
#!/bin/bash
/usr/local/bin/system-health-check.sh
echo "=== System Health Check ==="
echo "Date: $(date)"
echo
echo "Failed Services:"
systemctl --failed --no-legend
echo -e "\nBoot Time Analysis:"
systemd-analyze
echo -e "\nDisk Usage by Journal:"
journalctl --disk-usage
echo -e "\nTop 10 Slowest Services:"
systemd-analyze blame | head -10
```
2. Backup Important Configurations
```bash
Backup systemd configurations
sudo tar -czf systemd-backup-$(date +%Y%m%d).tar.gz \
/etc/systemd/system/ \
/etc/systemd/user/ \
/etc/systemd/system.conf
```
3. Documentation
Always document custom services and targets:
```ini
[Unit]
Description=My Custom Web Application Server
Documentation=https://internal-wiki.company.com/myapp
Documentation=man:myapp(8)
```
Migration Strategies
From SysV to Systemd
1. Inventory existing services:
```bash
chkconfig --list > sysv-services.txt
```
2. Create systemd equivalents:
```bash
Convert SysV script to systemd service
sudo systemd-sysv-generator
```
3. Test thoroughly:
```bash
Test service functionality
sudo systemctl start myservice
systemctl status myservice
```
4. Update automation scripts:
```bash
Replace old commands
OLD: service apache2 start
NEW: systemctl start apache2
```
Migration from Runlevels to Targets
Understanding the Mapping
When migrating from SysV to systemd, understand the conceptual mapping:
```bash
Create compatibility script
#!/bin/bash
runlevel-to-target.sh
case "$1" in
0) systemctl isolate poweroff.target ;;
1) systemctl isolate rescue.target ;;
2) systemctl isolate multi-user.target ;;
3) systemctl isolate multi-user.target ;;
4) systemctl isolate multi-user.target ;;
5) systemctl isolate graphical.target ;;
6) systemctl isolate reboot.target ;;
*) echo "Usage: $0 {0|1|2|3|4|5|6}" ;;
esac
```
Migration Checklist
1. Audit Current Configuration:
- List all custom SysV scripts
- Document service dependencies
- Note custom runlevel configurations
2. Create Systemd Units:
- Convert init scripts to service files
- Define proper dependencies
- Test service functionality
3. Update Automation:
- Modify deployment scripts
- Update monitoring tools
- Train team members
4. Testing Strategy:
- Test in development environment
- Validate service startup order
- Verify system behavior in different targets
Advanced Systemd Features
Socket Activation
```ini
/etc/systemd/system/myapp.socket
[Unit]
Description=MyApp Socket
[Socket]
ListenStream=8080
Accept=no
[Install]
WantedBy=sockets.target
```
Path-Based Activation
```ini
/etc/systemd/system/process-files.path
[Unit]
Description=Monitor directory for new files
[Path]
PathChanged=/var/spool/myapp
Unit=process-files.service
[Install]
WantedBy=multi-user.target
```
Device-Based Activation
```ini
[Unit]
Description=USB Device Handler
BindsTo=dev-disk-by\x2dlabel-MYUSB.device
After=dev-disk-by\x2dlabel-MYUSB.device
[Service]
Type=oneshot
ExecStart=/usr/local/bin/handle-usb.sh
[Install]
WantedBy=multi-user.target
```
Conclusion
Understanding runlevels and targets is essential for effective Linux system administration. This comprehensive guide has covered the evolution from traditional SysV runlevels to modern systemd targets, providing you with both theoretical knowledge and practical skills.
Key Takeaways
1. Historical Context: SysV runlevels provided a simple but limited approach to system state management
2. Modern Approach: Systemd targets offer greater flexibility, better performance, and more sophisticated dependency management
3. Practical Skills: You now know how to manage services, troubleshoot issues, and implement best practices
4. Migration Path: Understanding both systems helps in managing legacy systems and modern deployments
Next Steps
To further enhance your system administration skills:
1. Practice: Set up test environments with both SysV and systemd systems
2. Experiment: Create custom services and targets for real-world scenarios
3. Monitor: Implement regular system health checks and monitoring
4. Learn: Explore advanced systemd features like containers and user sessions
5. Document: Maintain documentation for your custom configurations
Professional Development
Consider these areas for continued learning:
- Container Technologies: Docker and systemd integration
- Automation: Ansible, Puppet, or Chef for service management
- Monitoring: Prometheus, Grafana, and systemd integration
- Security: Systemd security features and hardening
- Performance: Advanced systemd tuning and optimization
By mastering runlevels and targets, you've gained fundamental knowledge that applies across all Linux distributions and deployment scenarios. This understanding forms the foundation for advanced system administration, DevOps practices, and infrastructure management.
Remember that system administration is an evolving field, and staying current with new developments in systemd and Linux initialization systems will serve you well throughout your career. Regular practice, continuous learning, and hands-on experimentation are key to maintaining and expanding your expertise in this critical area of Linux system administration.