OpenRC: Init System ที่ยืดหยุ่นและมีประสิทธิภาพสำหรับ Linux

Introduction: ทำความเข้าใจ Init System

Init System คือคืออะไร?

Init System เป็นโปรแกรมแรกที่ถูกเรียกใช้งานโดย Linux kernel หลังจากที่ระบบบูตเสร็จสิ้น มีหน้าที่หลักดังนี้:

ประวัติศาสตร์ของ Init Systems

%%{init: {'theme':'base', 'themeVariables': {'primaryTextColor':'#000000', 'secondaryTextColor':'#000000', 'tertiaryTextColor':'#000000', 'fontSize':'16px'}}}%%
timeline
    title Timeline ของ Init System ของ Linux
    
    1983 : SysV init
         : System V Unix init
         : ระบบ init แบบดั้งเดิม
    
    1991 : Linux เกิดขึ้น
         : ใช้ SysV init style
    
    2001 : daemontools
         : runit เริ่มพัฒนา
         : ทางเลือกสำหรับ SysV
    
    2006 : Upstart
         : พัฒนาโดย Canonical (Ubuntu)
         : Event-based init
         : แทนที่ SysV ใน Ubuntu
    
    2007 : OpenRC
         : พัฒนาโดย Gentoo
         : Dependency-based init
    
    2010 : systemd เริ่มต้น
         : พัฒนาโดย Lennart Poettering
         : ประกาศโครงการ
    
    2011 : systemd v1.0
         : Fedora 15 นำมาใช้
    
    2012 : systemd แพร่หลาย
         : Arch Linux นำมาใช้
         : openSUSE นำมาใช้
    
    2014 : Debian ใช้ systemd
         : การโหวตเลือก systemd
         : Ubuntu เปลี่ยนมาใช้ systemd
    
    2015 : systemd กลายเป็น standard
         : ใช้ใน distro ส่วนใหญ่
         : RHEL 7 ใช้ systemd
    
    2016-ปัจจุบัน : systemd ครองตลาด
                : ใช้ใน major distros เกือบทั้งหมด
                : OpenRC, runit ยังมีใน niche distros
                : Gentoo, Void Linux ใช้ทางเลือกอื่น

OpenRC: ภาพรวม

OpenRC คืออะไร?

OpenRC เป็น dependency-based init system ที่พัฒนาโดยชุมชน Gentoo Linux เริ่มต้นในปี 2007 โดยมีจุดประสงค์เพื่อปรับปรุง init scripts ของ Gentoo ให้มีความยืดหยุ่นและจัดการ dependencies ได้ดีขึ้น

คุณสมบัติเด่นของ OpenRC

  1. Dependency-based: จัดการลำดับการเริ่มต้น services อัตโนมัติตาม dependencies
  2. ความเรียบง่าย: ใช้ shell scripts ที่อ่านและแก้ไขได้ง่าย
  3. Cross-platform: รองรับทั้ง Linux และ BSD systems
  4. Parallel Service Startup: เริ่มต้น services แบบขนานกันเพื่อความเร็ว
  5. Flexible Configuration: มีตัวเลือกการตั้งค่าที่หลากหลาย
  6. ไม่ต้องการ systemd: ทางเลือกสำหรับผู้ที่ต้องการความเรียบง่าย

โครงสร้างของ OpenRC

graph TB
    A[Linux Kernel] --> B[OpenRC PID 1]
    B --> C[rc-service]
    B --> D[openrc-run]
    B --> E[openrc-init]
    
    C --> F[/etc/init.d/]
    D --> G[Service Scripts]
    E --> H[Boot Process]
    
    F --> I[Individual Services]
    G --> I
    H --> J[Runlevels]
    
    J --> K[boot]
    J --> L[default]
    J --> M[shutdown]
    
    style B fill:#f9f,stroke:#333,stroke-width:4px
    style C fill:#bbf,stroke:#333,stroke-width:2px
    style D fill:#bbf,stroke:#333,stroke-width:2px
    style E fill:#bbf,stroke:#333,stroke-width:2px

การเปรียบเทียบ Init Systems

ตารางเปรียบเทียบคุณสมบัติ

คุณสมบัติ OpenRC systemd SysVinit runit
ปีที่เริ่มพัฒนา 2007 2010 1983 2004
ภาษาที่ใช้เขียน Shell Script C Shell Script C
Dependency Management ✅ มี ✅ มี ❌ ไม่มี ⚠️ จำกัด
Parallel Startup ✅ มี ✅ มี ❌ ไม่มี ✅ มี
ขนาดโค้ด ~20K SLOC ~1.3M SLOC ~5K SLOC ~3K SLOC
ความซับซ้อน ต่ำ-ปานกลาง สูง ต่ำ ต่ำมาก
Cross-platform ✅ Linux, BSD ❌ Linux only ✅ Unix-like ✅ Unix-like
Configuration Format Shell Scripts Unit Files Shell Scripts Directory-based
Service Supervision ⚠️ จำกัด ✅ มี ❌ ไม่มี ✅ มี
Socket Activation ❌ ไม่มี ✅ มี ❌ ไม่มี ❌ ไม่มี
Logging syslog/logger journald syslog svlogd
Timer Support ⚠️ ใช้ cron ✅ มี (timers) ⚠️ ใช้ cron ⚠️ ใช้ cron

ข้อดีและข้อเสียเปรียบเทียบ

OpenRC

ข้อดี:

ข้อเสีย:

systemd

ข้อดี:

ข้อเสีย:

SysVinit

ข้อดี:

ข้อเสีย:

runit

ข้อดี:

ข้อเสีย:

การติดตั้ง OpenRC

สำหรับ Gentoo Linux

# OpenRC มาพร้อมกับ Gentoo อยู่แล้ว
emerge --ask sys-apps/openrc

สำหรับ Alpine Linux

# Alpine ใช้ OpenRC เป็นค่าเริ่มต้น
apk add openrc

สำหรับ Artix Linux

# ติดตั้ง OpenRC package
pacman -S openrc openrc-system

การแปลงจาก systemd มาเป็น OpenRC

# ใน Artix Linux
# 1. ติดตั้ง OpenRC
pacman -S openrc-system

# 2. ลบ systemd
pacman -Rdd systemd

# 3. ติดตั้ง OpenRC init
pacman -S openrc openrc-init

# 4. รีบูตระบบ
reboot

โครงสร้างไดเรกทอรีและไฟล์

ไดเรกทอรีสำคัญ

/etc/init.d/          # Service scripts
/etc/conf.d/          # Service configuration files
/etc/runlevels/       # Runlevel configurations
├── boot/             # Services for boot runlevel
├── default/          # Services for default runlevel
├── shutdown/         # Services for shutdown
└── sysinit/          # System initialization
/etc/rc.conf          # Global OpenRC configuration
/lib/rc/              # OpenRC library files
/var/log/rc.log       # OpenRC log file

กระบวนการ Boot ของ OpenRC

graph TD
    A[Kernel Loaded] --> B[OpenRC Init PID 1]
    B --> C[sysinit Runlevel]
    C --> C1[devfs - Mount /dev]
    C --> C2[dmesg - Kernel messages]
    C --> C3[udev/mdev - Device management]
    
    C1 --> D[boot Runlevel]
    C2 --> D
    C3 --> D
    
    D --> D1[fsck - File system check]
    D --> D2[root - Mount root filesystem]
    D --> D3[localmount - Mount local filesystems]
    D --> D4[hostname - Set hostname]
    D --> D5[networking - Network initialization]
    
    D1 --> E[default Runlevel]
    D2 --> E
    D3 --> E
    D4 --> E
    D5 --> E
    
    E --> E1[sshd - SSH daemon]
    E --> E2[cronie - Cron daemon]
    E --> E3[nginx - Web server]
    E --> E4[Custom Services]
    
    E1 --> F[System Ready]
    E2 --> F
    E3 --> F
    E4 --> F
    
    style B fill:#f96,stroke:#333,stroke-width:4px
    style C fill:#ff9,stroke:#333,stroke-width:2px
    style D fill:#9f9,stroke:#333,stroke-width:2px
    style E fill:#9ff,stroke:#333,stroke-width:2px
    style F fill:#f9f,stroke:#333,stroke-width:4px

คำสั่งพื้นฐานของ OpenRC

การจัดการ Services

ดูสถานะ service

# ดูสถานะของ service เดียว
rc-service sshd status

# ดูสถานะทั้งหมด
rc-status

# ดูสถานะแบบละเอียด
rc-status -v

# ดูสถานะ service ใน runlevel เฉพาะ
rc-status default

เริ่ม, หยุด, รีสตาร์ท services

# เริ่ม service
rc-service nginx start

# หยุด service
rc-service nginx stop

# รีสตาร์ท service
rc-service nginx restart

# โหลดการตั้งค่าใหม่
rc-service nginx reload

# ตรวจสอบ configuration
rc-service nginx checkconfig

เพิ่ม/ลบ services จาก runlevel

# เพิ่ม service ไปยัง default runlevel
rc-update add nginx default

# ลบ service จาก runlevel
rc-update del nginx default

# ดูรายการ services ใน runlevels
rc-update show

# ดูรายการ services ทั้งหมดที่มี
rc-update show -v

การจัดการ Runlevels

# เปลี่ยน runlevel
openrc default

# รีบูตระบบ
openrc reboot

# ปิดระบบ
openrc shutdown

# ดู runlevel ปัจจุบัน
rc-status --runlevel

คำสั่งขั้นสูง

# อัปเดต dependency cache
rc-update -u

# Dry-run การเปลี่ยนแปลง
rc-update add nginx default --dry-run

# แสดง dependencies ของ service
rc-service --ifexists --ifstopped sshd start --nodeps

# Debug service
rc-service nginx start --debug

การสร้าง Service Script

โครงสร้างพื้นฐานของ Service Script

Service script ใน OpenRC เป็น shell script ที่มีโครงสร้างเฉพาะ มาดูตัวอย่างกัน

ตัวอย่างที่ 1: Simple Service

สร้างไฟล์ /etc/init.d/myapp

#!/sbin/openrc-run
# Copyright 2025 Your Name
# Distributed under the terms of the GNU General Public License v2

description="My Custom Application"

command="/usr/bin/myapp"
command_args="${myapp_args:---config /etc/myapp/config.conf}"
pidfile="/run/myapp.pid"
command_background=true

depend() {
    need net
    use logger dns
    after firewall
}

start_pre() {
    # ตรวจสอบว่า config file มีอยู่
    if [ ! -f /etc/myapp/config.conf ]; then
        eerror "Configuration file not found!"
        return 1
    fi
    
    # สร้าง directories ที่จำเป็น
    checkpath --directory --mode 0755 --owner myapp:myapp /var/log/myapp
    checkpath --directory --mode 0755 --owner myapp:myapp /var/run/myapp
}

start_post() {
    einfo "MyApp started successfully"
}

stop_post() {
    einfo "Cleaning up..."
    rm -f /var/run/myapp/*.tmp
}

สร้างไฟล์ configuration /etc/conf.d/myapp

# Configuration for myapp

# Command line arguments
myapp_args="--config /etc/myapp/config.conf --verbose"

# User and group
myapp_user="myapp"
myapp_group="myapp"

# Resource limits
rc_ulimit="-n 4096"

ตัวอย่างที่ 2: Web Application Service

สร้างไฟล์ /etc/init.d/webapp

#!/sbin/openrc-run
# Web Application Service

description="My Web Application"
description_reload="Reload configuration"
description_checkconfig="Check configuration"

command="/usr/bin/node"
command_args="/opt/webapp/server.js"
command_user="webapp:webapp"
command_background=true
pidfile="/run/webapp.pid"

# Output redirection
output_log="/var/log/webapp/output.log"
error_log="/var/log/webapp/error.log"

# Respawn if crashed
supervisor="supervise-daemon"
respawn_delay=5
respawn_max=5
respawn_period=60

depend() {
    need net localmount
    use dns logger mysql postgresql redis
    after firewall nginx
    provide web-app
}

start_pre() {
    # ตรวจสอบ Node.js
    if ! command -v node >/dev/null 2>&1; then
        eerror "Node.js is not installed"
        return 1
    fi
    
    # ตรวจสอบ application files
    if [ ! -f /opt/webapp/server.js ]; then
        eerror "Application files not found"
        return 1
    fi
    
    # สร้าง directories
    checkpath --directory --mode 0755 --owner webapp:webapp /var/log/webapp
    checkpath --directory --mode 0755 --owner webapp:webapp /run/webapp
    checkpath --directory --mode 0755 --owner webapp:webapp /opt/webapp/tmp
    
    # ล้าง temp files
    rm -rf /opt/webapp/tmp/*
    
    einfo "Starting web application..."
}

checkconfig() {
    # ตรวจสอบ syntax ของ config
    /usr/bin/node /opt/webapp/check-config.js
    return $?
}

reload() {
    ebegin "Reloading webapp configuration"
    
    if [ ! -f "${pidfile}" ]; then
        eerror "webapp is not running"
        return 1
    fi
    
    # ส่ง SIGHUP เพื่อโหลด config ใหม่
    kill -HUP $(cat ${pidfile})
    eend $?
}

stop_post() {
    # Cleanup
    einfo "Cleaning up temporary files..."
    rm -rf /opt/webapp/tmp/*
    rm -f /run/webapp/*.sock
}

Configuration file /etc/conf.d/webapp

# Web Application Configuration

# Environment variables
export NODE_ENV="production"
export PORT="3000"
export DATABASE_URL="postgresql://localhost/webapp"

# Resource limits
rc_ulimit="-n 8192"  # Max open files

# Nice level
rc_nice="-10"

ตัวอย่างที่ 3: Advanced Service with Multiple Instances

สร้างไฟล์ /etc/init.d/worker

#!/sbin/openrc-run
# Background Worker Service - supports multiple instances

instance="${RC_SVCNAME#worker.}"
description="Background Worker ${instance}"

if [ "${instance}" = "worker" ]; then
    instance="default"
fi

command="/usr/bin/python3"
command_args="/opt/workers/worker.py --instance ${instance}"
command_user="worker:worker"
command_background=true
pidfile="/run/worker.${instance}.pid"
output_log="/var/log/worker/worker.${instance}.log"
error_log="/var/log/worker/worker.${instance}.error.log"

supervisor="supervise-daemon"
respawn_delay=10
respawn_max=3
respawn_period=300

depend() {
    need net
    use logger redis rabbitmq
    after postgresql
}

start_pre() {
    # ตรวจสอบ Python
    if ! command -v python3 >/dev/null 2>&1; then
        eerror "Python 3 is not installed"
        return 1
    fi
    
    # สร้าง directories
    checkpath --directory --mode 0755 --owner worker:worker /var/log/worker
    checkpath --directory --mode 0755 --owner worker:worker /run/worker
    
    # โหลด configuration สำหรับ instance นี้
    if [ -f "/etc/worker/worker.${instance}.conf" ]; then
        . "/etc/worker/worker.${instance}.conf"
        export WORKER_CONFIG="/etc/worker/worker.${instance}.conf"
    else
        ewarn "No specific configuration found for instance ${instance}"
        ewarn "Using default configuration"
    fi
    
    einfo "Starting worker instance: ${instance}"
}

stop_pre() {
    einfo "Stopping worker instance: ${instance}"
}

การใช้งาน multiple instances:

# สร้าง symlinks สำหรับแต่ละ instance
ln -s /etc/init.d/worker /etc/init.d/worker.email
ln -s /etc/init.d/worker /etc/init.d/worker.image
ln -s /etc/init.d/worker /etc/init.d/worker.video

# เพิ่มไปยัง runlevel
rc-update add worker.email default
rc-update add worker.image default
rc-update add worker.video default

# จัดการแต่ละ instance
rc-service worker.email start
rc-service worker.image start
rc-service worker.video start

ตัวอย่างที่ 4: Service with Health Check

สร้างไฟล์ /etc/init.d/api-server

#!/sbin/openrc-run
# API Server with Health Check

description="API Server with health monitoring"
description_healthcheck="Check service health"

command="/usr/bin/api-server"
command_args="--port ${API_PORT:-8080}"
command_user="apiserver:apiserver"
command_background=true
pidfile="/run/api-server.pid"

supervisor="supervise-daemon"
healthcheck_delay=30
healthcheck_timer=60

depend() {
    need net
    use dns logger postgresql redis
    after firewall
}

start_pre() {
    checkpath --directory --mode 0755 --owner apiserver:apiserver /var/log/api-server
    checkpath --directory --mode 0755 --owner apiserver:apiserver /run/api-server
    
    # ตรวจสอบ database connection
    einfo "Checking database connection..."
    if ! su -s /bin/sh apiserver -c "psql ${DATABASE_URL} -c 'SELECT 1' >/dev/null 2>&1"; then
        eerror "Cannot connect to database"
        return 1
    fi
}

healthcheck() {
    ebegin "Checking API server health"
    
    # ตรวจสอบว่า process ยังทำงานอยู่
    if [ ! -f "${pidfile}" ]; then
        eend 1 "PID file not found"
        return 1
    fi
    
    local pid=$(cat "${pidfile}")
    if ! kill -0 ${pid} 2>/dev/null; then
        eend 1 "Process is not running"
        return 1
    fi
    
    # ตรวจสอบ health endpoint
    local health_url="http://localhost:${API_PORT:-8080}/health"
    local response=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "${health_url}" 2>/dev/null)
    
    if [ "${response}" = "200" ]; then
        eend 0 "Health check passed"
        return 0
    else
        eend 1 "Health check failed (HTTP ${response})"
        
        # Auto-restart if health check fails
        if [ "${AUTO_RESTART:-yes}" = "yes" ]; then
            ewarn "Auto-restarting service..."
            rc-service api-server restart
        fi
        return 1
    fi
}

stop_post() {
    # Graceful shutdown - wait for connections to close
    einfo "Waiting for connections to close..."
    local wait_time=0
    local max_wait=30
    
    while [ ${wait_time} -lt ${max_wait} ]; do
        if ! netstat -an | grep -q ":${API_PORT:-8080}.*ESTABLISHED"; then
            einfo "All connections closed"
            break
        fi
        sleep 1
        wait_time=$((wait_time + 1))
    done
    
    if [ ${wait_time} -ge ${max_wait} ]; then
        ewarn "Timeout waiting for connections"
    fi
}

Dependencies ใน OpenRC

ประเภทของ Dependencies

depend() {
    # need: service ที่จำเป็นต้องทำงานก่อน (hard dependency)
    need net localmount
    
    # use: service ที่ควรทำงานก่อนถ้ามี (soft dependency)
    use dns logger
    
    # want: เหมือน use แต่ไม่ warning ถ้าไม่มี
    want bluetooth
    
    # after: ทำงานหลังจาก service นี้ (order dependency)
    after firewall postgresql
    
    # before: ทำงานก่อน service นี้
    before nginx apache2
    
    # provide: ประกาศว่า service นี้ให้บริการอะไร
    provide database
    
    # keyword: platform-specific directives
    keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
}

ตัวอย่าง Dependency Chain

graph LR
    A[localmount] --> B[postgresql]
    A --> C[mysql]
    D[net] --> B
    D --> C
    D --> E[redis]
    
    B --> F[webapp]
    C --> F
    E --> F
    
    G[nginx] --> H[System Ready]
    F --> G
    
    style A fill:#f9f,stroke:#333,stroke-width:2px
    style D fill:#f9f,stroke:#333,stroke-width:2px
    style B fill:#ff9,stroke:#333,stroke-width:2px
    style C fill:#ff9,stroke:#333,stroke-width:2px
    style E fill:#ff9,stroke:#333,stroke-width:2px
    style F fill:#9f9,stroke:#333,stroke-width:2px
    style G fill:#9ff,stroke:#333,stroke-width:2px
    style H fill:#f96,stroke:#333,stroke-width:4px

การตั้งค่า Global Configuration

ไฟล์ /etc/rc.conf

# Global OpenRC Configuration

# ระบบ
rc_parallel="YES"              # เปิดใช้ parallel startup
rc_logger="YES"                # บันทึก log
rc_log_path="/var/log/rc.log" # ตำแหน่งไฟล์ log

# Network
rc_hotplug="YES"               # รองรับ hotplug devices
rc_depend_strict="YES"         # strict dependency checking

# Shell
rc_shell=/bin/sh              # Shell ที่ใช้

# Startup/Shutdown
rc_send_sighup="NO"           # ส่ง SIGHUP เมื่อ reload
rc_send_sigterm="NO"          # ส่ง SIGTERM เมื่อ stop
rc_timeout_stopsec=90         # Timeout สำหรับการ stop (วินาที)

# TTY
unicode="YES"                 # รองรับ UTF-8
rc_tty_number=12             # จำนวน TTY ที่สร้าง

Use Cases และตัวอย่างการใช้งานจริง

Use Case 1: ติดตั้ง Web Server Stack

# 1. ติดตั้ง packages
apk add nginx postgresql php-fpm

# 2. เตรียม services
rc-service postgresql setup

# 3. เพิ่ม services ไปยัง default runlevel
rc-update add nginx default
rc-update add postgresql default
rc-update add php-fpm default

# 4. เริ่มต้น services
rc-service postgresql start
rc-service php-fpm start
rc-service nginx start

# 5. ตรวจสอบสถานะ
rc-status

Use Case 2: Custom Development Environment

สร้างไฟล์ /etc/init.d/devenv

#!/sbin/openrc-run

description="Development Environment Setup"

depend() {
    need localmount net
    after docker postgresql redis
}

start() {
    ebegin "Starting development environment"
    
    # เริ่ม database containers
    docker start dev-postgres dev-redis dev-mongo
    
    # รอให้ databases พร้อม
    sleep 5
    
    # เริ่ม development servers
    su - developer -c "cd /home/developer/project && npm run dev &"
    
    eend $?
}

stop() {
    ebegin "Stopping development environment"
    
    # หยุด development servers
    pkill -f "npm run dev"
    
    # หยุด containers
    docker stop dev-postgres dev-redis dev-mongo
    
    eend $?
}

Use Case 3: Backup Service

สร้างไฟล์ /etc/init.d/backup-service

#!/sbin/openrc-run

description="Automated Backup Service"

command="/usr/local/bin/backup-daemon"
command_background=true
pidfile="/run/backup-service.pid"

depend() {
    need localmount net
    use logger
    after postgresql mysql
}

start_pre() {
    # ตรวจสอบพื้นที่
    local available=$(df /backup | tail -1 | awk '{print $4}')
    local required=10485760  # 10GB in KB
    
    if [ ${available} -lt ${required} ]; then
        eerror "Insufficient disk space for backups"
        eerror "Available: ${available}KB, Required: ${required}KB"
        return 1
    fi
    
    checkpath --directory --mode 0700 --owner root:root /backup
    einfo "Backup location ready: /backup"
}

Use Case 4: Monitoring Service

สร้างไฟล์ /etc/init.d/monitor

#!/sbin/openrc-run

description="System Monitoring Service"
description_status="Show monitoring status"

command="/usr/local/bin/monitor-daemon"
command_args="--config /etc/monitor/config.yaml"
command_background=true
pidfile="/run/monitor.pid"
command_user="monitor:monitor"

retry="TERM/30/KILL/5"

depend() {
    need net
    use logger dns
}

start_pre() {
    checkpath --directory --mode 0755 --owner monitor:monitor /var/log/monitor
    checkpath --directory --mode 0755 --owner monitor:monitor /var/lib/monitor
    
    # ตรวจสอบ configuration
    /usr/local/bin/monitor-daemon --config /etc/monitor/config.yaml --check-config
    local ret=$?
    
    if [ ${ret} -ne 0 ]; then
        eerror "Configuration validation failed"
        return 1
    fi
}

extra_started_commands="status"

status() {
    einfo "Monitoring Service Status:"
    /usr/local/bin/monitor-ctl status
}

Troubleshooting และ Debugging

การ Debug Services

# เปิด verbose logging
RC_DEBUG=yes rc-service myservice start

# ดู log file
tail -f /var/log/rc.log

# Debug dependency
rc-service myservice start --nodeps

# ตรวจสอบ syntax ของ init script
sh -n /etc/init.d/myservice

# ทดสอบ start_pre function
. /etc/init.d/myservice
start_pre

ปัญหาที่พบบ่อยและวิธีแก้

1. Service ไม่สามารถเริ่มได้

# ตรวจสอบ dependencies
rc-service --debug myservice start

# ตรวจสอบ log
grep myservice /var/log/rc.log

# ตรวจสอบ permissions
ls -l /etc/init.d/myservice
ls -l /run/myservice.pid

2. Service เริ่มช้า

# ตรวจสอบ startup time
time rc-service myservice start

# ดู dependencies ที่ทำให้ช้า
rc-service --ifexists --debug myservice start

# พิจารณาเปลี่ยน 'need' เป็น 'use' ถ้าเป็นไปได้

3. Dependency Issues

# อัปเดต dependency cache
rc-update -u

# ตรวจสอบ circular dependencies
rc-depend --show myservice

# ลบ dependency cache และสร้างใหม่
rm -rf /lib/rc/cache
rc-update -u

เครื่องมือช่วย Debug

# ดู service dependencies
rc-depend --depend myservice

# ดู services ที่ขึ้นกับ service นี้
rc-depend --depend myservice --rev

# ตรวจสอบ runlevel configuration
rc-status --all

# ดู crashed services
rc-status --crashed

# ทดสอบ service script
sh -x /etc/init.d/myservice start

Performance Tuning

เพิ่มความเร็วในการ Boot

# 1. เปิด parallel startup
echo 'rc_parallel="YES"' >> /etc/rc.conf

# 2. ลด timeout
echo 'rc_timeout_stopsec=30' >> /etc/rc.conf

# 3. ใช้ use แทน need เมื่อเป็นไปได้
# ใน /etc/init.d/myservice
depend() {
    use logger dns  # แทนที่ need
}

# 4. ลบ services ที่ไม่จำเป็น
rc-update del service-name default

การวัดเวลา Boot

สร้างสคริปต์ /usr/local/bin/boot-time.sh

#!/bin/sh
# แสดงเวลาในการ boot แต่ละ service

grep -E "Starting|Started" /var/log/rc.log | \
while read line; do
    echo "$line"
done | \
awk '{
    if ($3 == "Starting") {
        start[$4] = $1" "$2
    } else if ($3 == "Started") {
        if (start[$4]) {
            print $4, "took:", $1" "$2, "-", start[$4]
        }
    }
}'

Best Practices

1. การเขียน Service Scripts

2. การจัดการ Dependencies

3. การตั้งค่า Security

# ใน init script
command_user="service-user:service-group"  # อย่าใช้ root
umask 027  # กำหนด default permissions

# ใน start_pre()
checkpath --directory --mode 0750 --owner user:group /var/lib/service

4. Logging

# เปิด logging
rc_logger="YES"

# ใช้ output redirection
output_log="/var/log/service/output.log"
error_log="/var/log/service/error.log"

# Log rotation - ใน /etc/logrotate.d/service
/var/log/service/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
}

สรุป

OpenRC เป็น init system ที่มีความยืดหยุ่นและมีประสิทธิภาพ เหมาะสำหรับผู้ที่:

คุณสมบัติหลัก

✅ Dependency-based startup
✅ Parallel service execution
✅ Shell script configuration
✅ Cross-platform (Linux/BSD)
✅ Service supervision (ด้วย supervise-daemon)
✅ ยืดหยุ่นและปรับแต่งได้ง่าย

ข้อจำกัด

⚠️ ไม่มี socket activation
⚠️ Service supervision จำกัดกว่า systemd
⚠️ Documentation น้อยกว่า
⚠️ Community เล็กกว่า

Distributions ที่ใช้ OpenRC

แหล่งข้อมูลเพิ่มเติม

Documentation

ชุมชน

Tools และ Utilities

# OpenRC tools
rc-service    # จัดการ services
rc-status     # ดูสถานะ
rc-update     # จัดการ runlevels
openrc-run    # รัน init scripts
rc-depend     # แสดง dependencies

# ยูทิลิตี้เสริม
openrc-init   # PID 1 init system
supervise-daemon  # Process supervisor
start-stop-daemon # Start/stop daemons