Skip to content

Commit

Permalink
[sonic_ssd] add ssd_emmc.py with EmmcUtil (sonic-net#362)
Browse files Browse the repository at this point in the history
EmmcUtil class implements SsdBase API and can be used by ssdutil instead
of the default SsdUtil class on platforms that have eMMC.
The class is copied from Arista platform.

Signed-off-by: Yakiv Huryk <[email protected]>
  • Loading branch information
Yakiv-Huryk authored Apr 15, 2023
1 parent 9c73610 commit 082dc93
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
51 changes: 51 additions & 0 deletions sonic_platform_base/sonic_ssd/ssd_emmc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#
# ssd_emmc.py
#
# Implementation of SSD Utility API for eMMC.
# It reads eMMC health, model, firmware, and serial from /sys/block/*.
#

try:
import os
from .ssd_base import SsdBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")


class EmmcUtil(SsdBase):
def __init__(self, diskdev):
self.diskdev = diskdev
self.path = os.path.join('/sys/block', os.path.basename(diskdev))

def _read_device_entry(self, entry, default=None):
path = os.path.join(self.path, 'device', entry)
try:
with open(path) as f:
return f.read().rstrip()
except OSError:
return default

def _is_slc(self):
return bool(self._read_device_entry('enhanced_area_offset'))

def get_health(self):
data = self._read_device_entry('life_time')
if data is None:
raise NotImplementedError
value = int(data.split()[0 if self._is_slc() else 1], 0)
return float(100 - (10 * (value - 1)))

def get_temperature(self):
return 'N/A'

def get_model(self):
return self._read_device_entry('name')

def get_firmware(self):
return self._read_device_entry('fwrev')

def get_serial(self):
return self._read_device_entry('serial')

def get_vendor_output(self):
return ''
40 changes: 40 additions & 0 deletions tests/ssd_emmc_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import sys
if sys.version_info.major == 3:
from unittest.mock import mock_open, patch
else:
from mock import mock_open, patch

from sonic_platform_base.sonic_ssd.ssd_emmc import EmmcUtil

mocked_files = {
'/sys/block/emmctest/device/enhanced_area_offset': '0',
'/sys/block/emmctest/device/life_time': '0x02 0x02',
'/sys/block/emmctest/device/name': 'Test eMMC device',
'/sys/block/emmctest/device/fwrev': '0xAA00000000000000',
'/sys/block/emmctest/device/serial': '0xabcdefef'
}


def build_mocked_sys_fs_open(files):
mocks = dict([(fname, mock_open(read_data=cnt).return_value)
for fname, cnt in files.items()])

def mopen(fname):
if fname in mocks:
return mocks[fname]
else:
raise FileNotFoundError(fname)
return mopen


class TestSsdEMMC:

@patch('builtins.open', new=build_mocked_sys_fs_open(mocked_files))
def test_check(self, *args):
util = EmmcUtil('emmctest')

assert (util.get_health() == 90.0)
assert (util.get_temperature() == 'N/A')
assert (util.get_model() == 'Test eMMC device')
assert (util.get_firmware() == '0xAA00000000000000')
assert (util.get_serial() == '0xabcdefef')

0 comments on commit 082dc93

Please sign in to comment.