Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nvme manager support #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ACLOCAL_AMFLAGS = -I m4
AM_DEFAULT_SOURCE_EXT = .cpp
bin_PROGRAMS = nvme_main

nvme_main_SOURCES = \
nvme_main.cpp \
nvme_manager.cpp \
smbus.cpp \
nvmes.cpp


nvme_main_LDFLAGS = \
-lstdc++fs \
$(SDBUSPLUS_LIBS) \
$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
$(SDEVENTPLUS_LIBS)

nvme_main_CXX_FLAGS = \
$(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
$(SDBUSPLUS_CFLAGS) \
$(PHOSPHOR_LOGGING_CFLAGS)

nvmedir = $(sysconfdir)/nvme
nvme_DATA = nvme_config.json
156 changes: 156 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
### phosphor-nvme

#### Introduction

phosphor-nvme is the nvme manager service maintains for NVMe drive information
update and related notification processing service. The service update
information to `xyz/openbmc_project/Nvme/Status.interface.yaml`,
`xyz/openbmc_project/Sensor/Value.interface.yaml` and
other interfaces in `xyz.openbmc_project.Inventory.Manager`.

#### General usage

The service `xyz.openbmc_project.nvme.manager` provides object on D-Bus:

* /xyz/openbmc_project/sensors/temperature/nvme(index)

where object implements interface `xyz.openbmc_project.Sensor.Value`.

NVMe drive export as sensor and sensor value is temperature of drive.
It can get the sensor value of the drive through ipmitool command `sdr elist`
if the corresponding settings in the sensor map are configured correctly.
For example:

* To get sensor value:

```
### With ipmi command on BMC
ipmitool sdr elist
```

The service also updates other NVMe drive information to D-bus
`xyz.openbmc_project.Inventory.Manager`. The service
`xyz.openbmc_project.Inventory.Manager` provides object on D-Bus:

* /xyz/openbmc_project/inventory/system/chassis/motherboard/nvme(index)

where object implements interfaces:

* xyz.openbmc_project.Inventory.Item
* xyz.openbmc_project.Inventory.Decorator.Asset
* xyz.openbmc_project.Nvme.Status

Interface `xyz.openbmc_project.Nvme.Status` with the following properties:

| Property | Type | Description |
| -------- | ---- | ----------- |
| SmartWarnings| string | Indicates smart warnings for the state |
| StatusFlags | string | Indicates the status of the drives |
| DriveLifeUsed | string | A vendor specific estimate of the percentage |
| TemperatureFault| bool | If warning type about temperature happened |
| BackupdrivesFault | bool | If warning type about backup drives happened |
| CapacityFault| bool | If warning type about capacity happened |
| DegradesFault| bool | If warning type about degrades happened |
| MediaFault| bool | If warning type about media happened |

Interface `xyz.openbmc_project.Inventory.Item` with the following properties:

| Property | Type | Description |
| -------- | ---- | ----------- |
| Present | bool | Whether or not the item is present |

Interface `xyz.openbmc_project.Inventory.Decorator.Asset` with the following
properties:

| Property | Type | Description |
| -------- | ---- | ----------- |
| SerialNumber | string | The item serial number |
| Manufacturer | string | The item manufacturer |

Each property in the inventory manager can be obtained via the busctl
get-property command. For example:

* To get property Present:

```
### With busctl on BMC
busctl get-property xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard/nvme0 xyz.openbmc_project.Inventory.Item Present
```

#### Configuration file

There is a JSON configuration file `nvme_config.json` for drive index, bus ID,
and the LED object path and bus name for each drive.
For example,

```json
{
"config": [
{
"NvmeDriveIndex": 0,
"NVMeDriveBusID": 16,
"NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_0_fault",
"NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_0_locate",
"NVMeDriveLocateLEDControllerBusName":"xyz.openbmc_project.LED.Controller.led_u2_0_locate",
"NVMeDriveLocateLEDControllerPath":"/xyz/openbmc_project/led/physical/led_u2_0_locate",
"NVMeDrivePresentPin": 148,
"NVMeDrivePwrGoodPin": 161
},
{
"NvmeDriveIndex": 1,
"NVMeDriveBusID": 17,
"NVMeDriveFaultLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_1_fault",
"NVMeDriveLocateLEDGroupPath": "/xyz/openbmc_project/led/groups/led_u2_1_locate",
"NVMeDriveLocateLEDControllerBusName":"xyz.openbmc_project.LED.Controller.led_u2_1_locate",
"NVMeDriveLocateLEDControllerPath":"/xyz/openbmc_project/led/physical/led_u2_1_locate",
"NVMeDrivePresentPin": 149,
"NVMeDrivePwrGoodPin": 162
}
],
"threshold":[
{
"criticalHigh":70,
"criticalLow":0,
"maxValue":70,
"minValue":0
}
]
}
```

* config
* NvmeDriveIndex: The index of the NVMe drive, which will be displayed in the
object path.
* NVMeDriveBusID: The bus id of the NVMe drive, since it communicates with SMBus.
* NVMeDriveFaultLEDGroupPath: Object path of fault LED in LED Group Manager.
* NVMeDriveLocateLEDGroupPath: Object path of locate LED in LED Group Manager.
* NVMeDriveLocateLEDControllerBusName: D-Bus name of locate LED in LED Controller.
* NVMeDriveLocateLEDControllerPath: Object path of locate LED in LED Controller.
* NVMeDrivePresentPin: Gpio present pin of NVMe drive.
* NVMeDrivePwrGoodPin: Gpio Power good pin of NVMe drive.
* threshold
* criticalHigh: Upper critical threshold.
* criticalLow: Lower critical threshold.
* maxValue: Sensor maximum value.
* minValue: Sensor value.

#### Process

1. It will register a D-bus called `xyz.openbmc_project.nvme.manager`
description above.
2. Obtain the drive index, bus ID, GPIO present pin, power good pin and fault
LED object path from the json file mentioned above.
3. Each cycle will do following steps:
1. Check if the present pin of target drive is true, if true, means drive
exists and go to next step. If not, means drive does not exists and
remove object path from D-bus by drive index.
2. Check if the power good pin of target drive is true, if true means drive
is ready then create object path by drive index and go to next step. If
not, means drive power abnormal, turn on fault LED and log in journal.
3. Send a NVMe-MI command via SMBus Block Read protocol by bus ID of target
drive to get data. Data get from NVMe drives are "Status Flags",
"SMART Warnings", "Temperature", "Percentage Drive Life Used",
"Vendor ID", and "Serial Number".
4. The data will be set to the properties in D-bus.

This service will run automatically and look up NVMe drives every second.
96 changes: 96 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Initialization
AC_PREREQ([2.69])
AC_INIT([phosphor-nvme], [0.1])
AC_LANG([C++])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([subdir-objects -Wall foreign dist-xz])
AM_SILENT_RULES([yes])

# Checks for programs.
AC_PROG_CXX
AM_PROG_AR
AC_PROG_INSTALL
AC_PROG_MAKE_SET

# Checks compiler characteristics.
AX_CXX_COMPILE_STDCXX_17([noext])
AX_APPEND_COMPILE_FLAGS([-Wall -Wno-unused-variable], [CXXFLAGS])

# Checks for modules
PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus],, [AC_MSG_ERROR([Could not find sdbusplus...openbmc/sdbusplus package required])])
PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging],, [AC_MSG_ERROR([Could not find phosphor-logging...openbmc/phosphor-logging package required])])
PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces],, [AC_MSG_ERROR([Could not find phosphor-dbus-interfaces...openbmc/phosphor-dbus-interfaces package required])])
PKG_CHECK_MODULES([SDEVENTPLUS], [sdeventplus], [], [AC_MSG_ERROR(["sdeventplus required and not found."])])

# Dbus service name
AC_ARG_VAR(NVME_REQUEST_NAME, [The Dbus busname to own])
AS_IF([test "x$NVME_REQUEST_NAME" == "x"], [NVME_REQUEST_NAME="xyz.openbmc_project.nvme.manager"])
AC_DEFINE_UNQUOTED([NVME_REQUEST_NAME], ["$NVME_REQUEST_NAME"], [The Dbus busname to own])

# Service dbus root
AC_ARG_VAR(NVME_OBJ_PATH_ROOT, [The nvme Dbus root])
AS_IF([test "x$NVME_OBJ_PATH_ROOT" == "x"], [NVME_OBJ_PATH_ROOT="/xyz/openbmc_project/sensors/temperature"])
AC_DEFINE_UNQUOTED([NVME_OBJ_PATH_ROOT], ["$NVME_OBJ_PATH_ROOT"], [The nvme Dbus root])

# Service dbus objpath
AC_ARG_VAR(NVME_OBJ_PATH, [The nvme object path])
AS_IF([test "x$NVME_OBJ_PATH" == "x"], [NVME_OBJ_PATH="/xyz/openbmc_project/sensors/temperature/nvme"])
AC_DEFINE_UNQUOTED([NVME_OBJ_PATH], ["$NVME_OBJ_PATH"], [The nvme Dbus root])

# Service dbus interface
AC_ARG_VAR(DBUS_PROPERTY_IFACE, [The properies interface])
AS_IF([test "x$DBUS_PROPERTY_IFACE" == "x"], [DBUS_PROPERTY_IFACE="org.freedesktop.DBus.Properties"])
AC_DEFINE_UNQUOTED([DBUS_PROPERTY_IFACE], ["$DBUS_PROPERTY_IFACE"], [The nvme Dbus root])

# LED group service dbus busname
AC_ARG_VAR(LED_GROUP_BUSNAME, [The LED group manager dbus name])
AS_IF([test "x$LED_GROUP_BUSNAME" == "x"], [LED_GROUP_BUSNAME="xyz.openbmc_project.LED.GroupManager"])
AC_DEFINE_UNQUOTED([LED_GROUP_BUSNAME], ["$LED_GROUP_BUSNAME"], [The LED group manager dbus name])

# LED group interface
AC_ARG_VAR(LED_GROUP_IFACE, [The LED group manager interface])
AS_IF([test "x$LED_GROUP_IFACE" == "x"], [LED_GROUP_IFACE="xyz.openbmc_project.Led.Group"])
AC_DEFINE_UNQUOTED([LED_GROUP_IFACE], ["$LED_GROUP_IFACE"], [The LED group manager interface])

# LED controller interface
AC_ARG_VAR(LED_CONTROLLER_IFACE, [The LED controller interface])
AS_IF([test "x$LED_CONTROLLER_IFACE" == "x"], [LED_CONTROLLER_IFACE="xyz.openbmc_project.Led.Physical"])
AC_DEFINE_UNQUOTED([LED_CONTROLLER_IFACE], ["$LED_CONTROLLER_IFACE"], [The LED controller interface])

# item interface
AC_ARG_VAR(ITEM_IFACE, [The item interface])
AS_IF([test "x$ITEM_IFACE" == "x"], [ITEM_IFACE="xyz.openbmc_project.Inventory.Item"])
AC_DEFINE_UNQUOTED([ITEM_IFACE], ["$ITEM_IFACE"], [The item interface])

# NVMe status interface
AC_ARG_VAR(NVME_STATUS_IFACE, [The NVMe status interface])
AS_IF([test "x$NVME_STATUS_IFACE" == "x"], [NVME_STATUS_IFACE="xyz.openbmc_project.Nvme.Status"])
AC_DEFINE_UNQUOTED([NVME_STATUS_IFACE], ["$NVME_STATUS_IFACE"], [The NVMe status interface])

# Asset interface
AC_ARG_VAR(ASSET_IFACE, [The Asset interface])
AS_IF([test "x$ASSET_IFACE" == "x"], [ASSET_IFACE="xyz.openbmc_project.Inventory.Decorator.Asset"])
AC_DEFINE_UNQUOTED([ASSET_IFACE], ["$ASSET_IFACE"], [The Asset interface])

# Inventory dbus busname
AC_ARG_VAR(INVENTORY_BUSNAME, [The inventory busname])
AS_IF([test "x$INVENTORY_BUSNAME" == "x"], [INVENTORY_BUSNAME="xyz.openbmc_project.Inventory.Manager"])
AC_DEFINE_UNQUOTED([INVENTORY_BUSNAME], ["$INVENTORY_BUSNAME"], [The inventory busname])

# Inventory path
AC_ARG_VAR(INVENTORY_PATH, [The inventory path])
AS_IF([test "x$INVENTORY_PATH" == "x"], [INVENTORY_PATH="/xyz/openbmc_project/inventory/system/chassis/motherboard/nvme"])
AC_DEFINE_UNQUOTED([INVENTORY_PATH], ["$INVENTORY_PATH"], [The inventory path])

LT_INIT # Required for systemd linking

# Create configured output
AC_CONFIG_FILES([Makefile])
AC_OUTPUT







Loading