Przejdź do treści

🧰 Solaris SMF and Services

Solaris Service Management Facility (SMF) revolutionized Unix service management by providing a robust, dependency-aware framework. Understanding SMF is essential for effective Solaris administration.


🎯 SMF Architecture Overview

Core Concepts

SMF replaces traditional SysV init with a modern service management system:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# SMF Components
# - Repository: Central service database
# - restarter: Service lifecycle management
# - svc.startd: Master restarter daemon
# - svc.configd: Configuration daemon
# - Manifests: Service definitions (XML)
# - Profiles: Service enablement configurations

# SMF States
# - online: Service running normally
# - offline: Service administratively disabled
# - disabled: Service permanently disabled
# - maintenance: Service requires administrator attention
# - degraded: Service running with reduced functionality

SMF Repository Structure

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Repository locations
/etc/svc/repository.db      # Main repository database
/var/svc/manifest/          # Site-specific manifests
/lib/svc/manifest/          # System manifests

# Repository commands
svccfg repository export    # Export repository
svccfg repository import    # Import repository
svccfg repository backup    # Backup repository

# Repository inspection
svcprop -p general/entities repository  # Repository entities

🔧 Basic SMF Operations

Service Status and Information

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# List services
svcs                    # Brief service list
svcs -a                 # All services (including disabled)
svcs -v                 # Verbose output
svcs -x                 # Services in non-default states

# Check specific service
svcs ssh                # Service status
svcs network/ssh        # Full FMRI
svcs -l network/ssh     # Detailed service information

# Service dependencies
svcs -d network/ssh     # Services this depends on
svcs -D network/ssh     # Services depending on this

# Service properties
svcprop network/ssh     # All properties
svcprop -p start/exec network/ssh  # Specific property
svcprop -p general/enabled network/ssh  # Enabled status

Service Control Operations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Enable services
svcadm enable ssh                    # Enable by name
svcadm enable network/ssh           # Enable by FMRI
svcadm enable -r network/ssh        # Enable recursively
svcadm enable -s network/ssh        # Enable and wait for online

# Disable services
svcadm disable ssh                   # Disable by name
svcadm disable network/ssh          # Disable by FMRI
svcadm disable -t network/ssh       # Temporarily disable

# Restart services
svcadm restart ssh                  # Restart by name
svcadm restart network/ssh         # Restart by FMRI

# Refresh services (reload configuration)
svcadm refresh ssh                  # Refresh by name
svcadm refresh network/ssh         # Refresh by FMRI

# Clear maintenance state
svcadm clear network/ssh           # Clear maintenance

📋 Service Manifests

Manifest Structure

SMF manifests define services using XML:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!-- Example service manifest -->
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type='manifest' name='myservice'>
  <service name='application/myservice' type='service' version='1'>

    <!-- Dependencies -->
    <dependency name='network' grouping='require_all'
                restart_on='error' type='service'>
      <service_fmri value='svc:/milestone/network:default'/>
    </dependency>

    <!-- Execution methods -->
    <exec_method type='method' name='start'
                 exec='/lib/svc/method/myservice start'
                 timeout_seconds='60'>
      <method_context>
        <method_credential user='myservice' group='myservice'/>
      </method_context>
    </exec_method>

    <exec_method type='method' name='stop'
                 exec=':kill' timeout_seconds='60'/>

    <!-- Properties -->
    <property_group name='startd' type='framework'>
      <propval name='duration' type='astring' value='contract'/>
      <propval name='ignore_error' type='astring'
               value='core,signal'/>
    </property_group>

    <property_group name='application' type='application'>
      <propval name='config_file' type='astring'
               value='/etc/myservice.conf'/>
    </property_group>

    <!-- Stability -->
    <stability value='Evolving'/>

    <!-- Template information -->
    <template>
      <common_name>
        <loctext xml:lang='C'>My Custom Service</loctext>
      </common_name>
      <description>
        <loctext xml:lang='C'>Custom application service</loctext>
      </description>
    </template>
  </service>
</service_bundle>

Manifest Management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Import manifest
svccfg import /var/svc/manifest/site/myservice.xml

# Export service configuration
svccfg export network/ssh > ssh_manifest.xml

# Validate manifest
svccfg validate /var/svc/manifest/site/myservice.xml

# List manifests
svccfg inventory

# Delete service
svccfg delete application/myservice

🌐 Service Dependencies

Dependency Types

SMF manages complex service dependencies automatically:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Dependency categories
# - require_all: All dependencies must be satisfied
# - require_any: At least one dependency must be satisfied
# - optional_all: All optional dependencies (if present)
# - exclude_all: Service cannot run if any excluded

# Restart policies
# - none: Don't restart on dependency change
# - restart: Restart on dependency change
# - refresh: Refresh on dependency change
# - error: Disable service on dependency failure

# View dependencies
svcs -d network/ssh          # Required dependencies
svcs -d -i network/ssh       # Optional dependencies
svcs -d -x network/ssh       # Excluded dependencies

# Dependency chain analysis
svcs -D network/ssh          # Services depending on SSH
svcs -D -i network/ssh       # Services optionally depending on SSH

Milestone Services

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# System milestones
svcs milestone/*             # All milestones
svcs milestone/single-user   # Single-user milestone
svcs milestone/multi-user    # Multi-user milestone
svcs milestone/multi-user-server  # Multi-user server milestone

# Milestone dependencies
# network:default -> multi-user
# multi-user -> multi-user-server
# single-user -> multi-user transition

# Check milestone status
svcs -l milestone/multi-user
svcs -d milestone/multi-user-server

🛠️ Service Configuration

Property Management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# View properties
svcprop network/ssh                    # All properties
svcprop -p start/exec network/ssh     # Specific property
svcprop -p general/enabled network/ssh # Enabled status

# Set properties
svccfg -s network/ssh setprop general/enabled = false
svccfg -s network/ssh setprop start/exec = "/usr/local/bin/sshd -D"
svccfg -s network/ssh addpropgroup custom application
svccfg -s network/ssh setprop custom/port = 2222

# Refresh after property changes
svcadm refresh network/ssh

# Validate configuration
svccfg -s network/ssh listprop

Instance Management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Service instances
svcs -a | grep network/ssh    # Show all instances
svccfg -s network/ssh list    # List instances

# Create instance
svccfg -s network/ssh add demo
svccfg -s network/ssh:demo setprop general/enabled = true

# Delete instance
svccfg -s network/ssh delete demo

# Instance-specific operations
svcadm enable network/ssh:default
svcadm disable network/ssh:demo

🎨 Advanced SMF Features

Fault Management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Fault management
fmadm config              # FMRI configuration
fmadm faulty              # List faulty services
fmadm repaired fmri       # Mark fault as repaired
fmadm reset modname       # Reset module

# Service faults
svcs -xv                  # Verbose fault information
svcs -xv network/ssh      # Specific service faults

# Clear faults
svcadm clear network/ssh  # Clear maintenance state

Service Bundles and Profiles

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Service bundles
# Group related services
# Simplify management

# Profiles
svccfg apply /etc/svc/profile/generic.xml  # Apply profile
svccfg extract /etc/svc/profile/current.xml # Extract current

# Profile types
# - generic: Basic services
# - desktop: Desktop services
# - server: Server services
# - minimal: Minimal services

Custom Service Creation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# Create custom service script
cat > /lib/svc/method/myservice << 'EOF'
#!/sbin/sh
. /lib/svc/share/smf_include.sh

case "$1" in
    start)
        /usr/local/bin/myservice --daemon
        ;;
    stop)
        pkill -f myservice
        ;;
    *)
        echo "Usage: $0 {start|stop}"
        exit 1
        ;;
esac
exit $SMF_EXIT_OK
EOF

chmod 755 /lib/svc/method/myservice

# Create service manifest
cat > /var/svc/manifest/site/myservice.xml << 'EOF'
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type='manifest' name='myservice'>
  <service name='application/myservice' type='service' version='1'>
    <create_default_instance enabled='false'/>
    <single_instance/>

    <dependency name='network' grouping='require_all'
                restart_on='none' type='service'>
      <service_fmri value='svc:/milestone/network:default'/>
    </dependency>

    <exec_method type='method' name='start'
                 exec='/lib/svc/method/myservice start'
                 timeout_seconds='60'/>
    <exec_method type='method' name='stop'
                 exec='/lib/svc/method/myservice stop'
                 timeout_seconds='60'/>

    <property_group name='startd' type='framework'>
      <propval name='duration' type='astring' value='child'/>
    </property_group>

    <stability value='Unstable'/>
    <template>
      <common_name>
        <loctext xml:lang='C'>My Custom Service</loctext>
      </common_name>
    </template>
  </service>
</service_bundle>
EOF

# Import and enable service
svccfg import /var/svc/manifest/site/myservice.xml
svcadm enable myservice

🔍 Troubleshooting and Debugging

Service Diagnosis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Detailed service information
svcs -xv network/ssh           # Extended fault information
svcs -l network/ssh            # Service details
svcprop network/ssh            # Service properties

# Service logs
svcs -xv | grep log            # Find log files
tail -f $(svcs -L network/ssh) # Follow service log

# Method script debugging
/lib/svc/method/sshd start     # Test method script directly

Common Issues and Solutions

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Service won't start
# 1. Check dependencies: svcs -d service_name
# 2. Check logs: svcs -L service_name
# 3. Validate manifest: svccfg validate manifest.xml
# 4. Check properties: svcprop service_name

# Service in maintenance
# 1. Check logs for errors
# 2. Fix underlying issue
# 3. Clear maintenance: svcadm clear service_name

# Dependency issues
# 1. Check dependency services: svcs -d service_name
# 2. Enable required services: svcadm enable dependency
# 3. Refresh main service: svcadm refresh service_name

# Configuration issues
# 1. Check properties: svcprop service_name
# 2. Set correct properties: svccfg -s service setprop ...
# 3. Refresh service: svcadm refresh service_name

SMF Log Analysis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# SMF system logs
tail -f /var/svc/log/*        # Follow all service logs
grep "network/ssh" /var/adm/messages  # Service messages

# Service-specific logs
svcs -L network/ssh            # Get log file path
tail -f $(svcs -L network/ssh) # Follow log

# Debug logging
svccfg -s network/ssh setprop general/log_level = astring: debug
svcadm refresh network/ssh

🧾 Summary Quick Reference

Essential SMF Commands

Command Description
svcs List services
svcs -a List all services
svcs -x Services in non-default states
svcadm enable service Enable service
svcadm disable service Disable service
svcadm restart service Restart service
svcadm refresh service Refresh service
svcprop service Show service properties
svccfg import manifest.xml Import manifest

Service States

State Description
online Service running normally
offline Service administratively disabled
disabled Service permanently disabled
maintenance Service requires attention
degraded Service running with issues

🧠 Best Practices

SMF Administration Guidelines

Service Design: - Define clear dependencies - Use appropriate restart policies - Implement proper error handling - Provide meaningful service descriptions - Follow naming conventions

Configuration Management: - Use svcprop for property management - Validate manifests before import - Maintain backup configurations - Document service customizations - Test changes in non-production

Monitoring and Maintenance: - Regular service status checks - Monitor service logs - Implement proper alerting - Plan for service dependencies - Document service relationships

Common Mistakes to Avoid: - Bypassing SMF for service management - Ignoring service dependencies - Not validating manifests - Hard-coding paths in manifests - Disabling critical system services

Production Service Management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# Production service checklist:
# 1. Verify service dependencies
# 2. Test service startup/shutdown
# 3. Configure proper logging
# 4. Set appropriate timeouts
# 5. Implement monitoring
# 6. Document service requirements
# 7. Plan for failover scenarios

# Service health check script
service_health_check() {
    local service="$1"

    # Check service state
    if svcs -H -o state "$service" | grep -q online; then
        echo "Service $service is online"
    else
        echo "Service $service is not online"
        svcs -xv "$service"
        return 1
    fi

    # Check service dependencies
    local deps_ok=true
    for dep in $(svcs -H -o fmri -d "$service"); do
        if ! svcs -H -o state "$dep" | grep -q online; then
            echo "Dependency $dep is not online"
            deps_ok=false
        fi
    done

    if [ "$deps_ok" = true ]; then
        echo "All dependencies for $service are satisfied"
    else
        return 1
    fi
}

🧾 See Also