local singleton = require('mc.singleton')
local class = require('mc.class')
local common_def = require('common_def')
local initiator = require('mc.initiator')
local context = require('mc.context')
local client = require('storage.client')
local skynet = require('skynet')
local object_manage = require('mc.orm.object_manage')
local log = require('mc.logging')
local mdb = require('mc.mdb')
local method_misc = class()
local NOT_SUPPORT_OOB_CTRL_LIST = {
[10] = true,
[19] = true,
[20] = true,
}
function method_misc:remove_ele_by_position(list, position)
for i = #list, 1, -1 do
if list[i] and list[i].position == position then
table.remove(list, i)
break
end
end
end
function method_misc:update_if_valid(invalid, val, default)
if val and val ~= invalid then
return val
end
return default
end
function method_misc:test_controller_oob_support(type_id)
if not NOT_SUPPORT_OOB_CTRL_LIST[type_id] then
return true
end
return false
end
local function test_controller_vendor(type_id, vendor_id)
if vendor_id == common_def.VENDER_LSI then
if type_id < common_def.PMC_3152_8I_SMART_RAID then
return true
end
elseif vendor_id == common_def.VENDER_PMC then
if type_id >= common_def.PMC_3152_8I_SMART_RAID and type_id <= common_def.PMC_8222_8I_SMART_RAID then
return true
end
elseif vendor_id == common_def.VENDER_HUAWEI then
if type_id >= common_def.HI1880_SP186_M_16i and type_id <= common_def.HI1880_SP186_M_8i then
return true
end
elseif vendor_id == common_def.VENDER_HRDT then
if type_id == common_def.HRDT_B261s then
return true
end
end
return false
end
function method_misc:check_io_policy(io_policy, type_id)
if test_controller_vendor(type_id, common_def.VENDER_LSI) then
if io_policy > common_def.LD_CACHE_DIRECT_IO then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
elseif
test_controller_vendor(type_id, common_def.VENDER_PMC)
or test_controller_vendor(type_id, common_def.VENDER_HUAWEI)
or test_controller_vendor(type_id, common_def.VENDER_HRDT)
then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
return common_def.SM_CODE_SUCCESS
end
function method_misc:test_controller_vendor(type_id, vendor_id)
return test_controller_vendor(type_id, vendor_id)
end
function method_misc:check_is_suport_upgrade(type_id)
return type_id >= common_def.HI1880_SP686C_M_16i_2G and type_id <= common_def.HI1880_SP686C_M_40i_4G
end
function method_misc:check_boot_priority_param(boot_priority, type_id)
if test_controller_vendor(type_id, common_def.VENDER_LSI) then
if boot_priority ~= common_def.BOOT_PRIORITY_PRIMARY then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
elseif test_controller_vendor(type_id, common_def.VENDER_PMC) then
if boot_priority > common_def.BOOT_PRIORITY_ALL then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
elseif test_controller_vendor(type_id, common_def.VENDER_HUAWEI) then
if boot_priority > common_def.BOOT_PRIORITY_PRIMARY then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
elseif test_controller_vendor(type_id, common_def.VENDER_HRDT) then
if boot_priority > common_def.BOOT_PRIORITY_ALL then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
end
return common_def.SM_CODE_SUCCESS
end
function method_misc:check_boot_devices_count(boot_priority, controller_obj)
if not test_controller_vendor(controller_obj.TypeId, common_def.VENDER_HUAWEI) then
return common_def.SM_CODE_SUCCESS
end
if boot_priority ~= common_def.BOOT_PRIORITY_PRIMARY then
return common_def.SM_CODE_SUCCESS
end
if controller_obj.SupportedBootDeviceCount <= 1 then
return common_def.SM_CODE_SUCCESS
end
local count = 0
for _, name in ipairs(controller_obj.BootDevices) do
if name and name ~= 'None' then
count = count + 1
end
end
if count == controller_obj.SupportedBootDeviceCount then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
return common_def.SM_CODE_SUCCESS
end
function method_misc:check_read_policy(read_policy, type_id)
if test_controller_vendor(type_id, common_def.VENDER_LSI) then
if read_policy > common_def.READ_POLICY_READ_AHEAD_ADAPTIVE then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
elseif test_controller_vendor(type_id, common_def.VENDER_PMC) then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
elseif test_controller_vendor(type_id, common_def.VENDER_HUAWEI) then
if read_policy > common_def.LD_CACHE_READ_AHEAD then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
elseif test_controller_vendor(type_id, common_def.VENDER_HRDT) then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
return common_def.SM_CODE_SUCCESS
end
function method_misc:check_BGI(BGI_enable, type_id)
if test_controller_vendor(type_id, common_def.VENDER_LSI) then
if BGI_enable > common_def.LD_CACHE_DIRECT_IO then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
elseif
test_controller_vendor(type_id, common_def.VENDER_PMC)
or test_controller_vendor(type_id, common_def.VENDER_HUAWEI)
or test_controller_vendor(type_id, common_def.VENDER_HRDT)
then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
return common_def.SM_CODE_SUCCESS
end
function method_misc:get_boot_priority_op_desc(boot_priority, type_id)
if test_controller_vendor(type_id, common_def.VENDER_LSI) then
return common_def.AS_BOOT_DEVICE
end
if test_controller_vendor(type_id, common_def.VENDER_PMC) then
return 'boot priority to ' .. (common_def.PD_BOOT_PRIORITY[boot_priority] or common_def.INVALID_STRING)
end
if test_controller_vendor(type_id, common_def.VENDER_HUAWEI) then
return common_def.PD_BOOTABLE_DESC[boot_priority] or common_def.INVALID_STRING
end
if test_controller_vendor(type_id, common_def.VENDER_HRDT) then
return 'boot priority to ' .. (common_def.PD_BOOT_PRIORITY[boot_priority] or common_def.INVALID_STRING)
end
return common_def.INVALID_STRING
end
function method_misc:check_access_policy(access_policy, type_id)
if test_controller_vendor(type_id, common_def.VENDER_LSI) then
if access_policy > common_def.LD_ACCESS_BLOCKED then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
elseif
test_controller_vendor(type_id, common_def.VENDER_PMC)
or test_controller_vendor(type_id, common_def.VENDER_HUAWEI)
or test_controller_vendor(type_id, common_def.VENDER_HRDT)
then
return common_def.SM_CODE_PARA_DATA_ILLEGAL
end
return common_def.SM_CODE_SUCCESS
end
function method_misc:check_volume_name(name, type_id)
if self:check_ld_name_too_long(#name, type_id) then
return common_def.SM_CODE_LD_NAME_EXCEED_MAX_LEN
end
if not self:check_string_is_valid_ascii(name) then
return common_def.SM_CODE_LD_NAME_INVALID_ASCII
end
return common_def.SM_CODE_SUCCESS
end
function method_misc:get_ld_name_max_length(type_id)
if test_controller_vendor(type_id, common_def.VENDER_LSI) then
return 15
elseif test_controller_vendor(type_id, common_def.VENDER_PMC) then
return 64
elseif test_controller_vendor(type_id, common_def.VENDER_HUAWEI) then
return 20
elseif test_controller_vendor(type_id, common_def.VENDER_HRDT) then
return 20
end
return 0
end
function method_misc:check_ld_name_too_long(len, type_id)
if test_controller_vendor(type_id, common_def.VENDER_LSI) and len > common_def.SL_LD_NAME_LENGTH then
return true
end
if test_controller_vendor(type_id, common_def.VENDER_PMC) and len > common_def.SC_LD_NAME_LENGTH then
return true
end
if test_controller_vendor(type_id, common_def.VENDER_HUAWEI) and len > common_def.HS_LD_NAME_LENGTH then
return true
end
if test_controller_vendor(type_id, common_def.VENDER_HRDT) and len > common_def.HRDT_LD_NAME_LENGTH then
return true
end
return false
end
function method_misc:check_string_is_valid_ascii(name)
for i = 1, #name do
local ch = name:byte(i, i)
if ch > 0x7e or ch < 0x20 then
return false
end
end
return true
end
function method_misc:get_oob_interface_type(type_id)
if
test_controller_vendor(type_id, common_def.VENDER_HUAWEI)
or test_controller_vendor(type_id, common_def.VENDER_PMC)
then
return common_def.OOB_TYPE_OVER_PCIE
elseif
test_controller_vendor(type_id, common_def.VENDER_LSI)
or test_controller_vendor(type_id, common_def.VENDER_HRDT)
then
return common_def.OOB_TYPE_OVER_I2C
else
return common_def.INVALID_U8
end
end
function method_misc:get_op_initiator()
local m_initiator = initiator.new('N/A', 'N/A', 'localhost')
local ctx = context.get_context()
return (ctx and ctx:has_initiator()) and ctx:get_initiator() or m_initiator
end
function method_misc:get_manufacturer_name_by_oui(manufacturer_oui)
local vendor_id = tonumber(manufacturer_oui, 16)
if vendor_id and common_def.VENDOR_ID_2_VENDOR_NAME[vendor_id] then
return common_def.VENDOR_ID_2_VENDOR_NAME[vendor_id]
end
return 'ATA'
end
function method_misc:retry_register_firmware_info(
firmware_info_table,
updateable,
capability,
max_package_size_mib,
success_callback
)
skynet.fork(function()
local retries = 0
local max_retries = 3
local retry_interval = 5000
local ok, rsp
local param = {
Id = firmware_info_table.Id or '',
Name = firmware_info_table.Name or '',
Version = firmware_info_table.Version or '',
BuildNum = firmware_info_table.BuildNum or '',
ReleaseDate = firmware_info_table.ReleaseDate or '',
LowestSupportedVersion = firmware_info_table.LowestSupportedVersion or '',
SoftwareId = firmware_info_table.SoftwareId or '',
Manufacturer = firmware_info_table.Manufacturer or '',
Location = firmware_info_table.Location or '',
State = firmware_info_table.State or 'Enabled',
Severity = firmware_info_table.Severity or 'Informational',
EstimatedDuration = firmware_info_table.EstimatedDuration or '',
ComponentID = firmware_info_table.ComponentID or '255',
SubComponentID = firmware_info_table.SubComponentID or '4294967295',
FirmwareType = firmware_info_table.FirmwareType or '',
TargetUIDs = firmware_info_table.TargetUIDs or '',
ActiveCondition = firmware_info_table.ActiveCondition or '',
RelatedItem = firmware_info_table.RelatedItem or '',
StageSupported = firmware_info_table.StageSupported or 'false',
Model = firmware_info_table.Model or '',
}
while retries < max_retries do
ok, rsp = client:PFirmwareInventoryFirmwareInventoryAdd(
context.new(),
param,
updateable,
capability,
max_package_size_mib
)
if ok then
log:notice('[MethodMisc] register firmware info success, Id=%s, Version=%s', param.Id, param.Version)
if success_callback then
success_callback()
end
return
end
retries = retries + 1
if retries < max_retries then
log:info('[MethodMisc] register firmware info failed, retry %s/%s, err:%s', retries, max_retries, rsp)
skynet.sleep(retry_interval / 10)
else
log:error(
'[MethodMisc] register firmware info failed after %s retries, Id=%s, err:%s',
max_retries,
param.Id,
rsp
)
return
end
end
end)
end
function method_misc:retry_unregister_firmware_info(firmware_id, success_callback)
skynet.fork(function()
local retries = 0
local max_retries = 3
local retry_interval = 5000
local ok, rsp
while retries < max_retries do
ok, rsp = client:PFirmwareInventoryFirmwareInventoryDelete(context.new(), firmware_id)
if ok then
log:notice('[MethodMisc] unregister firmware info success, Id=%s', firmware_id)
if success_callback then
success_callback()
end
return
end
retries = retries + 1
if retries < max_retries then
log:info('[MethodMisc] unregister firmware info failed, retry %s/%s, err:%s', retries, max_retries, rsp)
skynet.sleep(retry_interval / 10)
else
log:error(
'[MethodMisc] unregister firmware info failed after %s retries, Id=%s, err:%s',
max_retries,
firmware_id,
rsp
)
return
end
end
end)
end
function method_misc:update_firmware_info(firmware_obj, revision)
skynet.fork_once(function()
local retries = 0
local max_retries = 3
local retry_interval = 5000
local ok, obj
while retries < max_retries do
ok, obj = pcall(
mdb.get_cached_object,
object_manage.get_instance().bus,
common_def.FWINVENTORY_PATH_PREFIX .. firmware_obj.NodeId,
common_def.FIRMWARE_INFO_INTERFACE
)
if ok and obj then
obj.Version = revision
log:notice('[Storage] %s update firmware info version to %s', firmware_obj.Name, revision)
break
end
retries = retries + 1
if retries < max_retries then
log:info(
'[Storage] %s get firmware info failed, retry %s/%s, err:%s',
firmware_obj.Name,
retries,
max_retries,
obj
)
skynet.sleep(retry_interval / 10)
else
log:error(
'[Storage] %s get firmware info failed after %s retries, path:%s err:%s',
firmware_obj.Name,
max_retries,
common_def.FWINVENTORY_PATH_PREFIX .. firmware_obj.NodeId,
obj
)
return
end
end
end)
end
return singleton(method_misc)