openUBMC uses an advanced microcomponent development architecture to abstract resources managed by the BMC into resource objects. Components communicate with each other through standard resource interfaces. The entire set of openUBMC services can be quickly started with parallel startup within a layer.
openUBMC Startup Framework
The openUBMC startup framework is implemented using *systemd + Skynet. systemd is used to start services. As the initialization system and system manager of the Linux system, systemd starts various services and processes in the system and manages their lifecycles. With systemd, openUBMC can easily monitor service status, control service start and stop, and manage log records and users of sub-services by process.
In addition, openUBMC uses Skynet as the underlying running framework. Skynet is a lightweight server framework implemented using C+Lua. It can send data packets from one service so that other services in the same process can receive them and trigger the corresponding callback functions for processing.
openUBMC Service Startup Features
- Parallel startup: The traditional initialization system uses the serial startup mode, that is, services are started one by one in a fixed sequence. systemd can start multiple services at the same time, which greatly improves the system startup speed.
- Dependency management: systemd uses a service startup mode based on dependencies. By defining dependencies between services, it ensures that services are started in the correct sequence and automatically handles dependency conflicts between services.
- Sub-service startup: Skynet starts sub-services in a single process service. Service runtime environments are decoupled from each other to reduce conflicts between services.
- Flexible configuration: openUBMC uses systemd to execute Skynet. In this process, you can also customize systemd to execute non-Skynet commands to start customized services.
- Independent restart: If a component service is abnormal and no other dependency items exist, you do not need to perform a full restart of openUBMC. Instead, you only need to restart the corresponding service.
openUBMC Startup Process
Starting Services with systemd
openUBMC uses systemd to start services in parallel (by executing Skynet and configuration files). In the entire process, services are started by defining the startup sequence and dependencies. The following uses the bmc_core service as an example (all systemd configurations are stored in the hica repository):
[Unit]
Description=bmc_core service
After=framework.service
Requires=dbus.service framework.service
[Service]
StandardOutput=tty
TTYPath=/dev/ttyS0
User=root
Restart=always
RestartSec=2
StartLimitInterval=0
EnvironmentFile=/dev/shm/dbus/.dbus
Environment="ROOT_DIR="
Environment="PROJECT_DIR="
WorkingDirectory=/opt/bmc/apps/hica
ExecStartPre=/bin/bash -c "uptime=`/bin/cat /proc/uptime |awk -F '.' '{print $1}'`; if [ $uptime -lt 100 ]; then /bin/sleep 30; fi"
ExecStart=bash -c 'exec -a bmc_core /opt/bmc/skynet/skynet /opt/bmc/apps/hica/subsys/bmc_core/config.cfg'
ExecStartPost=/bin/bash -c 'echo 0x21 > /proc/$MAINPID/coredump_filter'
KillMode=process
MemoryHigh=1000M
MemoryMax=1024M
LimitCORE=100000000
LimitSTACK=100000000
[Install]
WantedBy=multi-user.targetThe preceding is the configuration of systemd. For details, see systemd.
Unit: service unit description.Unit.Description: service process description.Unit.After: service startup time sequence. The service can be started only after the specified service is started.Unit.Requires: service startup time sequence. When the dependency item is restarted, the service is also restarted.Service: service environment configuration and constraints.Service.User: service startup account statement.Service.Restart: service restart mode.Service.RestartSec: service restart delay (unit: second).Service.StartLimitInterval: unlimited number of restart times.Service.Environmentxxx: environment variable configuration.Service.WorkingDirectory: service working path (final location on the server).Service.ExecStartPre: service startup preprocessing by capturing information in uptime for delay startup.Service.ExecStart: service startup command, which runs Skynet and its configuration file using the bash to start the service.Service.ExecStartPost: processing after service startup.Service.KillMode: method of killing the process when the unit service is stopped.Service.MemoryHigh: memory usage limit. If the memory usage of a process exceeds the limit, the running time of the process is reduced and the memory occupied by the process is quickly reclaimed.Service.MemoryMax: maximum memory usage. If the memory usage of a process exceeds the limit, out of memory is triggered to kill the process.Service.LimitCORE: maximum size of a core dump that can be created by a service process.Service.LimitSTACK: stack size limit of a service process.Install: defines the service installation location.Install.WantBy: defines the target for starting the service.
The startup configuration specifies the service startup sequence, dependent services, service user permissions, service restart mode, service startup prerequisites, and service execution commands.
Starting Sub-Services with Skynet
In the preceding description, systemd starts process services one by one. The service startup is essentially the Skynet service execution under the conditions defined in the configuration file. The configuration file defines the execution entry, environment, and sub-service required by Skynet. The bmc_core configuration file is as follows:
include "/opt/bmc/libmc/config.cfg"
config:set_root("/")
config:set_start("hica/subsys/bmc_core/service/main")
config:include_app("firmware_mgmt")
config:include_app("bmc_upgrade")
...
config:include_app("ipmi_core")
config:done()
MODULE_NAME = "bmc_core" --Service name
thread = 6 --Thread configuration
... --Environment configuration
OPERATE_LOG_PATH = '/var/log/operate_log'include: imports the basic configuration file.config:set_root: specifies the root path.config:set_start: service startup program entry.config:include_app: declares the path of the component contained in the service startup.config:done(): ends the config configuration declaration.MODULE_NAME: name of the module to be started.thread: number of started threads.
The service entry is defined in this configuration. hica/subsys/bmc_core/service/main is used to execute the fork of Skynet to start the sub-service.
-- hica/subsys/hardware/service/main
local skynet = require 'skynet'
local launch_control = require 'mc.launch_control'
skynet.start(function()
local module_name = skynet.getenv('MODULE_NAME')
...
skynet.uniqueservice('sd_bus') -- sd_bus service startup
launch_control.launch_components('bmc_core') -- bmc_core sub-service startup
end)Component Status Query Command
During component running, you can run the following commands to query the component status:
top -cbn 1 # View the started service, startup command, CPU usage, and memory usage.systemctl status # View the tree relationship between the openUBMC service startup process and its subprocesses.For more system-level information, see the log file located at dump_info/RTOSDump/sysinfo. These logs are collected using the One-Click Info Collection function.
More
For more configurations, see source code hica.