Redfish Guide

Configure and extend the Redfish API in OpenBMC.

Table of Contents

  1. Overview
  2. Setup & Configuration
    1. Build-Time Configuration (Yocto)
    2. Meson Build Options Reference
    3. Runtime Enable/Disable
    4. HTTPS Certificate Configuration
    5. Network Protocol Settings
    6. Session Configuration
    7. Account Service Configuration
    8. Event Service Configuration
    9. Telemetry Configuration
  3. Redfish Basics
    1. API Structure
    2. Common Operations
  4. Authentication
    1. Basic Authentication
    2. Session Authentication
    3. mTLS Authentication
  5. Power Operations
    1. Get Power State
    2. Power On/Off
    3. Reset Types
  6. Sensors
    1. List All Sensors
    2. Get Sensor Details
    3. Sensor Properties
  7. Thermal Management
    1. Get Thermal Info
    2. Response Structure
  8. User Management
    1. List Users
    2. Create User
    3. Modify User
    4. Delete User
    5. Roles
  9. Event Service
    1. List Subscriptions
    2. Create Subscription
    3. Delete Subscription
  10. Firmware Update
    1. Check Current Version
    2. Upload and Apply Firmware
  11. Redfish Aggregation
    1. Architecture
    2. Enable Aggregation
    3. Aggregation Service API
    4. Managing Aggregation Sources
    5. Aggregation Source Properties
    6. Connection Methods
    7. Accessing Aggregated Resources
    8. Resource Prefixing
    9. Aggregation Use Cases
      1. Multi-Node Server Management
      2. Unified Sensor Monitoring
      3. Centralized Log Collection
    10. Aggregation Configuration
      1. Trust Store for Satellite Certificates
      2. Aggregation with mTLS
    11. Troubleshooting Aggregation
      1. Check Aggregation Source Status
      2. Common Issues
      3. Debug Logging
  12. Logs
    1. Get Event Log
    2. Clear Log
  13. OEM Extensions
    1. OEM Resource Locations
    2. Implementing OEM Extensions
  14. bmcweb Configuration
    1. Build Options
    2. Common Options
  15. Adding Custom Routes
    1. Basic Route Handler
    2. Register in bmcweb
  16. Troubleshooting
    1. Service Not Responding
    2. Authentication Failures
    3. Missing Resources
  17. Deep Dive
    1. Request Routing Architecture
    2. Async D-Bus Query Pattern
    3. Event Service (SSE) Implementation
    4. OEM Extension Pattern
    5. Source Code Reference
  18. Examples
  19. References

Overview

Redfish is a modern, RESTful API standard for server management, replacing IPMI for most use cases. OpenBMC implements Redfish through bmcweb, including support for Redfish Aggregation to manage multiple BMCs from a single endpoint.

---
title: Redfish Architecture
---
flowchart TB
    clients["External Clients<br/>(curl, Redfish clients, WebUI)"]

    clients -->|"HTTPS/443"| bmcweb

    subgraph bmcweb["bmcweb"]
        direction LR
        subgraph handlers["Resource Handlers"]
            direction TB
            Systems
            Chassis
            Managers
            Account
            Event
            OEM
        end
        auth["Authentication<br/>(Basic, Session, mTLS)"]
    end

    bmcweb --> dbus["D-Bus<br/>(phosphor-* services, inventory, sensors)"]
ASCII-art version (for comparison)
┌──────────────────────────────────────────────────────────────────┐
│                      Redfish Architecture                        │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────────────────────────────────────────────────────────┐│
│  │                    External Clients                          ││
│  │            (curl, Redfish clients, WebUI)                    ││
│  └──────────────────────────┬───────────────────────────────────┘│
│                             │                                    │
│                         HTTPS/443                                │
│                             │                                    │
│  ┌──────────────────────────┴───────────────────────────────────┐│
│  │                        bmcweb                                ││
│  │                                                              ││
│  │   ┌──────────────────────────────────────────────────────┐   ││
│  │   │              Resource Handlers                       │   ││
│  │   │                                                      │   ││
│  │   │ Systems │ Chassis │ Managers │ Account │ Event │ OEM │   ││
│  │   └──────────────────────────────────────────────────────┘   ││
│  │                                                              ││
│  │   ┌──────────────────────────────────────────────────────┐   ││
│  │   │              Authentication                          │   ││
│  │   │         (Basic, Session, mTLS)                       │   ││
│  │   └──────────────────────────────────────────────────────┘   ││
│  └──────────────────────────┬───────────────────────────────────┘│
│                             │                                    │
│  ┌──────────────────────────┴───────────────────────────────────┐│
│  │                         D-Bus                                ││
│  │           (phosphor-* services, inventory, sensors)          ││
│  └──────────────────────────────────────────────────────────────┘│
└──────────────────────────────────────────────────────────────────┘

Setup & Configuration

Build-Time Configuration (Yocto)

Configure bmcweb features in your build:

# In your machine .conf or local.conf

# Enable/disable bmcweb features
EXTRA_OEMESON:pn-bmcweb = " \
    -Dredfish-dbus-log=enabled \
    -Dredfish-bmc-journal=enabled \
    -Dredfish-cpu-log=enabled \
    -Dredfish-host-logger=enabled \
    -Dinsecure-tftp-update=disabled \
    -Dinsecure-push-style-notification=disabled \
    -Dkvm=enabled \
    -Dvm-websocket=enabled \
    -Dvm-nbdproxy=enabled \
    -Dmutual-tls-auth=enabled \
    -Dhttp-body-limit=65 \
"

Meson Build Options Reference

Option Default Description
Core Features    
redfish enabled Core Redfish support
redfish-aggregation disabled Aggregation support
rest disabled Legacy REST API (deprecated)
Logging    
redfish-dbus-log enabled D-Bus logging
redfish-bmc-journal enabled BMC journal logs
redfish-cpu-log disabled CPU crash logs
redfish-host-logger enabled Host console logging
Remote Access    
kvm enabled KVM WebSocket
vm-websocket enabled Virtual Media WebSocket
vm-nbdproxy enabled NBD proxy for virtual media
Security    
mutual-tls-auth enabled mTLS support
insecure-tftp-update disabled Allow TFTP updates
insecure-push-style-notification disabled Push notifications
Limits    
http-body-limit 30 Max request body (MB)

Runtime Enable/Disable

# Check bmcweb status
systemctl status bmcweb

# Restart bmcweb
systemctl restart bmcweb

# Stop bmcweb (disables all Redfish/web access)
systemctl stop bmcweb
systemctl disable bmcweb

# View logs
journalctl -u bmcweb -f

HTTPS Certificate Configuration

# View current certificate
curl -k https://localhost/redfish/v1/CertificateService/CertificateLocations

# Generate self-signed certificate (on BMC)
openssl req -x509 -newkey rsa:2048 -keyout /etc/ssl/private/server.pem \
    -out /etc/ssl/certs/server.pem -days 365 -nodes \
    -subj "/CN=openbmc"

# Replace via Redfish
curl -k -u root:0penBmc -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "CertificateType": "PEM",
        "CertificateString": "<PEM-ENCODED-CERT>"
    }' \
    https://localhost/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates

Network Protocol Settings

# Get network protocol settings
curl -k -u root:0penBmc \
    https://localhost/redfish/v1/Managers/bmc/NetworkProtocol

# Enable/disable protocols via Redfish
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{
        "HTTPS": {"ProtocolEnabled": true, "Port": 443},
        "SSH": {"ProtocolEnabled": true, "Port": 22},
        "IPMI": {"ProtocolEnabled": true, "Port": 623},
        "NTP": {"ProtocolEnabled": true}
    }' \
    https://localhost/redfish/v1/Managers/bmc/NetworkProtocol

Session Configuration

# Get session service settings
curl -k -u root:0penBmc \
    https://localhost/redfish/v1/SessionService

# Configure session timeout (seconds)
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{"SessionTimeout": 3600}' \
    https://localhost/redfish/v1/SessionService

Account Service Configuration

# Get account policy
curl -k -u root:0penBmc \
    https://localhost/redfish/v1/AccountService

# Configure account lockout
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{
        "AccountLockoutThreshold": 5,
        "AccountLockoutDuration": 300,
        "MinPasswordLength": 8
    }' \
    https://localhost/redfish/v1/AccountService

Event Service Configuration

# Get event service settings
curl -k -u root:0penBmc \
    https://localhost/redfish/v1/EventService

# Enable/disable event service
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{
        "ServiceEnabled": true,
        "DeliveryRetryAttempts": 3,
        "DeliveryRetryIntervalSeconds": 60
    }' \
    https://localhost/redfish/v1/EventService

Telemetry Configuration

# Get telemetry service
curl -k -u root:0penBmc \
    https://localhost/redfish/v1/TelemetryService

# Create metric report
curl -k -u root:0penBmc -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "Id": "PowerMetrics",
        "Name": "Power Consumption Report",
        "MetricReportDefinitionType": "Periodic",
        "ReportUpdates": "Overwrite",
        "Schedule": {
            "RecurrenceInterval": "PT60S"
        },
        "Metrics": [
            {
                "MetricId": "TotalPower",
                "MetricProperties": ["/redfish/v1/Chassis/chassis/Power#/PowerControl/0/PowerConsumedWatts"]
            }
        ]
    }' \
    https://localhost/redfish/v1/TelemetryService/MetricReportDefinitions

Redfish Basics

API Structure

/redfish/v1/                        # Service Root
├── Systems/                        # Computer systems
│   └── system/                     # This system
│       ├── Processors/             # CPUs
│       ├── Memory/                 # DIMMs
│       ├── Storage/                # Storage devices
│       └── LogServices/            # System logs
├── Chassis/                        # Physical enclosures
│   └── chassis/                    # This chassis
│       ├── Power/                  # Power info
│       ├── Thermal/                # Thermal info
│       └── Sensors/                # All sensors
├── Managers/                       # BMC managers
│   └── bmc/                        # This BMC
│       ├── NetworkProtocol/        # Network services
│       ├── EthernetInterfaces/     # Network ports
│       └── LogServices/            # BMC logs
├── AccountService/                 # User management
│   ├── Accounts/                   # User accounts
│   └── Roles/                      # Privilege roles
├── SessionService/                 # Session management
├── EventService/                   # Event subscriptions
├── UpdateService/                  # Firmware updates
└── TelemetryService/               # Telemetry data

Common Operations

# Set up alias for convenience
alias bmcurl='curl -k -u root:0penBmc'

# Get service root
bmcurl https://localhost/redfish/v1/

# Get system info
bmcurl https://localhost/redfish/v1/Systems/system

# Get chassis info
bmcurl https://localhost/redfish/v1/Chassis/chassis

# Get BMC info
bmcurl https://localhost/redfish/v1/Managers/bmc

Authentication

Basic Authentication

curl -k -u root:0penBmc https://localhost/redfish/v1/Systems/system

Session Authentication

# Create session
curl -k -X POST \
    -H "Content-Type: application/json" \
    -d '{"UserName":"root","Password":"0penBmc"}' \
    https://localhost/redfish/v1/SessionService/Sessions

# Response includes X-Auth-Token header
# Use token for subsequent requests
curl -k -H "X-Auth-Token: <token>" \
    https://localhost/redfish/v1/Systems/system

# Delete session
curl -k -X DELETE \
    -H "X-Auth-Token: <token>" \
    https://localhost/redfish/v1/SessionService/Sessions/<session-id>

mTLS Authentication

Configure client certificates for mutual TLS authentication.


Power Operations

Get Power State

bmcurl https://localhost/redfish/v1/Systems/system | jq '.PowerState'

Power On/Off

# Power on
bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{"ResetType":"On"}' \
    https://localhost/redfish/v1/Systems/system/Actions/ComputerSystem.Reset

# Graceful shutdown
bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{"ResetType":"GracefulShutdown"}' \
    https://localhost/redfish/v1/Systems/system/Actions/ComputerSystem.Reset

# Force off
bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{"ResetType":"ForceOff"}' \
    https://localhost/redfish/v1/Systems/system/Actions/ComputerSystem.Reset

# Reboot
bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{"ResetType":"ForceRestart"}' \
    https://localhost/redfish/v1/Systems/system/Actions/ComputerSystem.Reset

Reset Types

Type Description
On Power on
ForceOff Immediate power off
GracefulShutdown Graceful OS shutdown
GracefulRestart Graceful reboot
ForceRestart Immediate reboot
Nmi Non-maskable interrupt

Sensors

List All Sensors

bmcurl https://localhost/redfish/v1/Chassis/chassis/Sensors | jq '.Members'

Get Sensor Details

bmcurl https://localhost/redfish/v1/Chassis/chassis/Sensors/CPU_Temp | jq

Sensor Properties

{
    "@odata.id": "/redfish/v1/Chassis/chassis/Sensors/CPU_Temp",
    "Name": "CPU Temp",
    "Reading": 45.0,
    "ReadingUnits": "Cel",
    "Status": {
        "State": "Enabled",
        "Health": "OK"
    },
    "Thresholds": {
        "UpperCritical": {"Reading": 95},
        "UpperCaution": {"Reading": 85},
        "LowerCritical": {"Reading": 0},
        "LowerCaution": {"Reading": 5}
    }
}

Thermal Management

Get Thermal Info

bmcurl https://localhost/redfish/v1/Chassis/chassis/Thermal | jq

Response Structure

{
    "Temperatures": [
        {
            "Name": "CPU Temp",
            "ReadingCelsius": 45,
            "Status": {"State": "Enabled", "Health": "OK"}
        }
    ],
    "Fans": [
        {
            "Name": "Fan0",
            "Reading": 5000,
            "ReadingUnits": "RPM",
            "Status": {"State": "Enabled", "Health": "OK"}
        }
    ]
}

User Management

List Users

bmcurl https://localhost/redfish/v1/AccountService/Accounts | jq '.Members'

Create User

bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "UserName": "newuser",
        "Password": "Password123!",
        "RoleId": "Operator",
        "Enabled": true
    }' \
    https://localhost/redfish/v1/AccountService/Accounts

Modify User

bmcurl -X PATCH \
    -H "Content-Type: application/json" \
    -d '{"Password": "NewPassword123!"}' \
    https://localhost/redfish/v1/AccountService/Accounts/newuser

Delete User

bmcurl -X DELETE \
    https://localhost/redfish/v1/AccountService/Accounts/newuser

Roles

Role Description
Administrator Full access
Operator Manage operations, no user management
ReadOnly Read-only access

Event Service

List Subscriptions

bmcurl https://localhost/redfish/v1/EventService/Subscriptions

Create Subscription

bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "Destination": "https://my-server:8080/events",
        "Protocol": "Redfish",
        "EventTypes": ["Alert", "StatusChange"],
        "Context": "MySubscription"
    }' \
    https://localhost/redfish/v1/EventService/Subscriptions

Delete Subscription

bmcurl -X DELETE \
    https://localhost/redfish/v1/EventService/Subscriptions/<id>

Firmware Update

Check Current Version

bmcurl https://localhost/redfish/v1/UpdateService/FirmwareInventory | jq

Upload and Apply Firmware

# Upload firmware image
curl -k -u root:0penBmc \
    -X POST \
    -H "Content-Type: application/octet-stream" \
    --data-binary @firmware.tar \
    https://localhost/redfish/v1/UpdateService

# Or use SimpleUpdate action
bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "TransferProtocol": "TFTP",
        "ImageURI": "tftp://192.168.1.100/firmware.tar"
    }' \
    https://localhost/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate

Redfish Aggregation

Redfish Aggregation allows a single BMC (the “Aggregator”) to present resources from multiple downstream BMCs through a unified API. This is useful for multi-node systems, disaggregated infrastructure, or centralized datacenter management.

Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                        Aggregation Architecture                         │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│                    ┌──────────────────────────────┐                     │
│                    │     Management Client        │                     │
│                    │  (Single Entry Point)        │                     │
│                    └──────────────┬───────────────┘                     │
│                                   │                                     │
│                              HTTPS/443                                  │
│                                   │                                     │
│                    ┌──────────────┴────────────────┐                    │
│                    │      Aggregating BMC          │                    │
│                    │   (bmcweb with aggregation)   │                    │
│                    │                               │                    │
│                    │  /redfish/v1/                 │                    │
│                    │  ├── AggregationService/      │                    │
│                    │  ├── Systems/                 │◄─── Aggregated     │
│                    │  ├── Chassis/                 │     from all       │
│                    │  └── Managers/                │     satellites     │
│                    └──────────────┬────────────────┘                    │
│                                   │                                     │
│              ┌────────────────────┼────────────────────┐                │
│              │                    │                    │                │
│         HTTPS/443            HTTPS/443            HTTPS/443             │
│              │                    │                    │                │
│   ┌──────────┴─────┐   ┌─────────┴──────┐   ┌────────┴───────┐          │
│   │  Satellite 1   │   │  Satellite 2   │   │  Satellite 3   │          │
│   │  (Node BMC)    │   │  (Node BMC)    │   │  (Node BMC)    │          │
│   │  192.168.1.10  │   │  192.168.1.11  │   │  192.168.1.12  │          │
│   └────────────────┘   └────────────────┘   └────────────────┘          │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Enable Aggregation

Enable the aggregation feature at build time:

# In your machine .conf or local.conf
EXTRA_OEMESON:pn-bmcweb = " \
    -Dredfish-aggregation=enabled \
"

Aggregation Service API

Once enabled, the AggregationService endpoint becomes available:

# Get aggregation service
bmcurl https://localhost/redfish/v1/AggregationService

# Response
{
    "@odata.id": "/redfish/v1/AggregationService",
    "@odata.type": "#AggregationService.v1_0_1.AggregationService",
    "Id": "AggregationService",
    "Name": "Aggregation Service",
    "Description": "Aggregation Service",
    "ServiceEnabled": true,
    "AggregationSources": {
        "@odata.id": "/redfish/v1/AggregationService/AggregationSources"
    },
    "ConnectionMethods": {
        "@odata.id": "/redfish/v1/AggregationService/ConnectionMethods"
    }
}

Managing Aggregation Sources

Aggregation sources define the downstream BMCs to aggregate:

# List configured aggregation sources
bmcurl https://localhost/redfish/v1/AggregationService/AggregationSources

# Add a new aggregation source (satellite BMC)
bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "HostName": "192.168.1.10",
        "UserName": "admin",
        "Password": "password",
        "Links": {
            "ConnectionMethod": {
                "@odata.id": "/redfish/v1/AggregationService/ConnectionMethods/Redfish"
            }
        }
    }' \
    https://localhost/redfish/v1/AggregationService/AggregationSources

# Get details of an aggregation source
bmcurl https://localhost/redfish/v1/AggregationService/AggregationSources/1

# Remove an aggregation source
bmcurl -X DELETE \
    https://localhost/redfish/v1/AggregationService/AggregationSources/1

Aggregation Source Properties

Property Type Description
HostName string IP address or hostname of satellite BMC
UserName string Authentication username
Password string Authentication password (write-only)
SNMP object SNMP community settings (optional)
Links.ConnectionMethod link Connection method to use
Links.ResourcesAccessed array Resources aggregated from this source

Connection Methods

Connection methods define how the aggregator connects to satellites:

# List available connection methods
bmcurl https://localhost/redfish/v1/AggregationService/ConnectionMethods

# Get connection method details
bmcurl https://localhost/redfish/v1/AggregationService/ConnectionMethods/Redfish

# Response
{
    "@odata.id": "/redfish/v1/AggregationService/ConnectionMethods/Redfish",
    "@odata.type": "#ConnectionMethod.v1_0_0.ConnectionMethod",
    "Id": "Redfish",
    "Name": "Redfish Connection Method",
    "ConnectionMethodType": "Redfish",
    "ConnectionMethodVariant": "Redfish"
}

Accessing Aggregated Resources

Aggregated resources appear with prefixed IDs to identify their source:

# List all systems (local + aggregated)
bmcurl https://localhost/redfish/v1/Systems

# Response includes aggregated systems
{
    "Members": [
        {"@odata.id": "/redfish/v1/Systems/system"},           # Local
        {"@odata.id": "/redfish/v1/Systems/agg1_system"},      # Satellite 1
        {"@odata.id": "/redfish/v1/Systems/agg2_system"}       # Satellite 2
    ]
}

# Access aggregated system
bmcurl https://localhost/redfish/v1/Systems/agg1_system

# The request is proxied to the satellite BMC

Resource Prefixing

Aggregated resources use prefixes to avoid ID collisions:

Local Resource Aggregated Resource (Source 1)
/Systems/system /Systems/agg1_system
/Chassis/chassis /Chassis/agg1_chassis
/Managers/bmc /Managers/agg1_bmc
/Sensors/CPU_Temp /Sensors/agg1_CPU_Temp

Aggregation Use Cases

Multi-Node Server Management

# Power on all aggregated systems
for sys in system agg1_system agg2_system agg3_system; do
    bmcurl -X POST \
        -H "Content-Type: application/json" \
        -d '{"ResetType":"On"}' \
        "https://localhost/redfish/v1/Systems/${sys}/Actions/ComputerSystem.Reset"
done

Unified Sensor Monitoring

# Get all temperature sensors across all nodes
bmcurl https://localhost/redfish/v1/Chassis | jq -r '.Members[]."@odata.id"' | \
while read chassis; do
    echo "=== ${chassis} ==="
    bmcurl "${chassis}/Thermal" | jq '.Temperatures[] | {Name, ReadingCelsius}'
done

Centralized Log Collection

# Collect event logs from all systems
bmcurl https://localhost/redfish/v1/Systems | jq -r '.Members[]."@odata.id"' | \
while read system; do
    echo "=== ${system} ==="
    bmcurl "${system}/LogServices/EventLog/Entries" | jq '.Members[:5]'
done

Aggregation Configuration

Trust Store for Satellite Certificates

Configure trusted certificates for satellite BMC connections:

# Add satellite certificate to trust store
bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "CertificateType": "PEM",
        "CertificateString": "<PEM-ENCODED-CERT>"
    }' \
    https://localhost/redfish/v1/Managers/bmc/Truststore/Certificates

Aggregation with mTLS

For mutual TLS authentication with satellites:

# Configure client certificate for satellite authentication
bmcurl -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "HostName": "192.168.1.10",
        "Links": {
            "ConnectionMethod": {
                "@odata.id": "/redfish/v1/AggregationService/ConnectionMethods/Redfish"
            }
        }
    }' \
    https://localhost/redfish/v1/AggregationService/AggregationSources

Troubleshooting Aggregation

Check Aggregation Source Status

# Get aggregation source status
bmcurl https://localhost/redfish/v1/AggregationService/AggregationSources/1 | jq '.Status'

# Response
{
    "State": "Enabled",
    "Health": "OK"
}

Common Issues

Issue Cause Solution
Source unreachable Network/firewall issue Check connectivity to satellite
Authentication failed Wrong credentials Verify username/password
Certificate error Untrusted satellite cert Add to trust store or disable verification
Resources not appearing Service not ready Wait for satellite to fully boot
Timeout errors Slow satellite response Increase timeout settings

Debug Logging

# Enable verbose bmcweb logging
# Edit /lib/systemd/system/bmcweb.service to add:
# Environment="BMCWEB_LOG_LEVEL=DEBUG"

systemctl daemon-reload
systemctl restart bmcweb
journalctl -u bmcweb -f | grep -i aggregat

Logs

Get Event Log

bmcurl https://localhost/redfish/v1/Systems/system/LogServices/EventLog/Entries | jq '.Members'

Clear Log

bmcurl -X POST \
    https://localhost/redfish/v1/Systems/system/LogServices/EventLog/Actions/LogService.ClearLog

OEM Extensions

OEM Resource Locations

OEM extensions appear under Oem properties:

{
    "@odata.id": "/redfish/v1/Systems/system",
    "Oem": {
        "OpenBMC": {
            "@odata.type": "#OemComputerSystem.v1_0_0.OpenBMC",
            "FirmwareProvisioning": {
                "ProvisioningStatus": "NotProvisioned"
            }
        }
    }
}

Implementing OEM Extensions

Add OEM properties in bmcweb handlers:

// In systems.hpp
nlohmann::json& oem = asyncResp->res.jsonValue["Oem"]["OpenBMC"];
oem["@odata.type"] = "#OemComputerSystem.v1_0_0.OpenBMC";
oem["MyCustomProperty"] = "value";

bmcweb Configuration

Build Options

# In your machine config or local.conf
EXTRA_OEMESON:pn-bmcweb = " \
    -Dredfish-dbus-log=enabled \
    -Dhttp-body-limit=65 \
    -Dinsecure-tftp-update=disabled \
    "

Common Options

Option Description
redfish-dbus-log Enable D-Bus based logging
insecure-tftp-update Allow TFTP firmware updates
http-body-limit Max request body size (MB)
mutual-tls-auth Enable mTLS
kvm Enable KVM support
vm-websocket Enable Virtual Media WebSocket

Adding Custom Routes

Basic Route Handler

Source Reference: Pattern based on bmcweb

// In a new file under redfish-core/lib/
#include <app.hpp>
#include <registries/privilege_registry.hpp>

namespace redfish
{

inline void requestRoutesMyOem(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Oem/MyVendor/MyResource")
        .privileges(redfish::privileges::getManager)
        .methods(boost::beast::http::verb::get)(
            [](const crow::Request&,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
                asyncResp->res.jsonValue["@odata.type"] =
                    "#MyResource.v1_0_0.MyResource";
                asyncResp->res.jsonValue["@odata.id"] =
                    "/redfish/v1/Oem/MyVendor/MyResource";
                asyncResp->res.jsonValue["Name"] = "My Custom Resource";
                asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
            });
}

} // namespace redfish

Register in bmcweb

// In src/webserver_main.cpp or appropriate location
#include "myoem.hpp"

// In main():
redfish::requestRoutesMyOem(app);

Troubleshooting

Service Not Responding

# Check bmcweb status
systemctl status bmcweb

# View logs
journalctl -u bmcweb -f

Authentication Failures

# Check session service
bmcurl https://localhost/redfish/v1/SessionService

# Verify account exists
bmcurl https://localhost/redfish/v1/AccountService/Accounts

Missing Resources

# Check if D-Bus service is running
busctl tree xyz.openbmc_project.ObjectMapper

# Query object mapper for resource
busctl call xyz.openbmc_project.ObjectMapper \
    /xyz/openbmc_project/object_mapper \
    xyz.openbmc_project.ObjectMapper \
    GetObject sas "/xyz/openbmc_project/inventory/system" 0

Deep Dive

Advanced implementation details for Redfish developers.

Request Routing Architecture

bmcweb uses a route registration pattern for handling HTTP requests:

┌─────────────────────────────────────────────────────────────────────────┐
│                    bmcweb Request Routing                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   HTTP Request: GET /redfish/v1/Chassis/chassis0/Thermal                │
│                                   │                                     │
│                                   ▼                                     │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │                    Crow HTTP Server                             │   │
│   │   (Boost.Beast HTTP, Boost.Asio I/O)                            │   │
│   └────────────────────────────┬────────────────────────────────────┘   │
│                                │                                        │
│                                ▼                                        │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │                    Route Matching                               │   │
│   │   Routes registered at startup via BMCWEB_ROUTE macro           │   │
│   │                                                                 │   │
│   │   Pattern: "/redfish/v1/Chassis/<str>/Thermal"                  │   │
│   │   Matches: chassis0 → extracted as parameter                    │   │
│   └────────────────────────────┬────────────────────────────────────┘   │
│                                │                                        │
│                                ▼                                        │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │                    Authentication Check                         │   │
│   │   ├── Session token validation                                  │   │
│   │   ├── Basic auth (if enabled)                                   │   │
│   │   └── mTLS certificate (if enabled)                             │   │
│   └────────────────────────────┬────────────────────────────────────┘   │
│                                │                                        │
│                                ▼                                        │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │                    Handler Function                             │   │
│   │   thermal.cpp::handleThermalGet()                               │   │
│   │   ├── Query D-Bus for sensor data                               │   │
│   │   ├── Build JSON response                                       │   │
│   │   └── Send response via asyncResp                               │   │
│   └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Route registration pattern:

// In redfish-core/lib/thermal.hpp
inline void requestRoutesThermal(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Thermal/")
        .privileges(redfish::privileges::getThermal)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleThermalGet, std::ref(app)));
}

Source reference: redfish-core/lib/

Async D-Bus Query Pattern

bmcweb uses async callbacks to avoid blocking the event loop:

┌─────────────────────────────────────────────────────────────────────────┐
│                    Async D-Bus Query Pattern                            │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   Handler receives asyncResp (shared_ptr to response object)            │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │ void handleChassisGet(                                          │   │
│   │     App& app,                                                   │   │
│   │     const crow::Request& req,                                   │   │
│   │     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,        │   │
│   │     const std::string& chassisId)                               │   │
│   │ {                                                               │   │
│   │     // asyncResp->res.jsonValue populated over multiple calls   │   │
│   │     // Response sent when asyncResp refcount reaches zero       │   │
│   └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
│   Multiple async queries in flight:                                     │
│   ┌────────────────────────────────────────────────────────────────┐    │
│   │ asyncResp │───▶ Query 1: Get Chassis info ──────┐              │    │
│   │           │───▶ Query 2: Get Power state ───────┤ All complete │    │
│   │           │───▶ Query 3: Get Thermal data ──────┤     │        │    │
│   │           │───▶ Query 4: Get LED state ─────────┘     ▼        │    │
│   │           │                              Response sent         │    │
│   └────────────────────────────────────────────────────────────────┘    │
│                                                                         │
│   Pattern for D-Bus async call:                                         │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │ crow::connections::systemBus->async_method_call(                │   │
│   │     [asyncResp](const boost::system::error_code& ec,            │   │
│   │                 const PropertiesType& props) {                  │   │
│   │         if (ec) {                                               │   │
│   │             messages::internalError(asyncResp->res);            │   │
│   │             return;                                             │   │
│   │         }                                                       │   │
│   │         // Populate asyncResp->res.jsonValue                    │   │
│   │     },                                                          │   │
│   │     service, objectPath, "org.freedesktop.DBus.Properties",     │   │
│   │     "GetAll", interface);                                       │   │
│   └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Event Service (SSE) Implementation

┌─────────────────────────────────────────────────────────────────────────┐
│                    Redfish Event Service                                │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   Event Flow:                                                           │
│   ┌────────────────┐     ┌────────────────┐     ┌────────────────┐      │
│   │ D-Bus Signal   │────▶│ Event Filter   │────▶│ SSE Stream /   │      │
│   │ (phosphor-*)   │     │ (subscription  │     │ Push Webhook   │      │
│   │                │     │  match rules)  │     │                │      │
│   └────────────────┘     └────────────────┘     └────────────────┘      │
│                                                                         │
│   Subscription Types:                                                   │
│   ├── SSE (Server-Sent Events) - persistent HTTP connection             │
│   │   GET /redfish/v1/EventService/SSE                                  │
│   │   Response: text/event-stream                                       │
│   │                                                                     │
│   └── Push Style (Webhook) - HTTP POST to destination                   │
│       POST to subscriber's Destination URL                              │
│                                                                         │
│   Event Types:                                                          │
│   ├── Alert - hardware alerts (thresholds, failures)                    │
│   ├── ResourceAdded - new resource created                              │
│   ├── ResourceRemoved - resource deleted                                │
│   ├── ResourceUpdated - resource property changed                       │
│   └── MetricReport - telemetry data                                     │
│                                                                         │
│   D-Bus Signal to Redfish Event Mapping:                                │
│   ┌──────────────────────────────────────────────────────────────────┐  │
│   │ D-Bus: PropertiesChanged on Sensor.Value                         │  │
│   │   └─▶ Redfish: Alert with MessageId "Threshold exceeded"         │  │
│   │                                                                  │  │
│   │ D-Bus: InterfacesAdded on Inventory path                         │  │
│   │   └─▶ Redfish: ResourceAdded for new inventory item              │  │
│   └──────────────────────────────────────────────────────────────────┘  │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

OEM Extension Pattern

// Example: Adding OEM data to an existing resource
// In redfish-core/lib/chassis.cpp

inline void handleChassisGet(...)
{
    // Standard Redfish properties
    asyncResp->res.jsonValue["@odata.type"] = "#Chassis.v1_16_0.Chassis";
    asyncResp->res.jsonValue["Id"] = chassisId;

    // Add OEM section
    nlohmann::json& oem = asyncResp->res.jsonValue["Oem"]["OpenBMC"];
    oem["@odata.type"] = "#OpenBMCChassis.v1_0_0.Chassis";

    // Query OEM-specific D-Bus properties
    crow::connections::systemBus->async_method_call(
        [asyncResp](const boost::system::error_code& ec,
                    const std::string& customProp) {
            if (!ec) {
                asyncResp->res.jsonValue["Oem"]["OpenBMC"]
                    ["CustomProperty"] = customProp;
            }
        },
        "xyz.openbmc_project.OEM.Service",
        objectPath,
        "org.freedesktop.DBus.Properties",
        "Get",
        "xyz.openbmc_project.OEM.CustomInterface",
        "CustomProperty");
}

Source Code Reference

Key implementation files in bmcweb:

File Description
src/webserver_main.cpp Server startup, route registration
include/sessions.hpp Session management
redfish-core/lib/systems.cpp /Systems resource
redfish-core/lib/chassis.cpp /Chassis resource
redfish-core/lib/sensors.cpp Sensor reading helpers
redfish-core/lib/log_services.cpp SEL/Event log
redfish-core/include/privileges.hpp Authorization
redfish-core/include/utils/dbus_utils.hpp D-Bus helpers

Examples

Working examples are available in the examples/redfish directory:

  • oem_resource.hpp - Custom OEM resource implementation
  • oem-schema.json - OEM schema definition
  • test_oem_resource.sh - OEM resource test script

References


Tested on: OpenBMC master, QEMU romulus


Back to top

OpenBMC Guide Tutorial is not affiliated with the OpenBMC project. Content is provided for educational purposes.

This site uses Just the Docs, a documentation theme for Jekyll.