Replace applying flag by dict for FEC device check

This change replaces the latest solution to check FEC device before an
unlock action, that relied on an '/APPLYING' flag. In certain asynchro-
nous scenarios, that flag could be cleared before than expected if an
inventory report not related to the FEC device configuration came late
(that might happen when configuring a long queue of SRIOV port changes)
or by periodic sysinv report.
The solution still uses the 'extra_info' field of PCI devices, this
time "stringifying" a dictionary entry for 'expected_numvfs' that will
keep (without clearing) at that field the programmed number of VFs at
FEC device. It is then compared with the actual sriov_numvfs of device
from the inventory report, in a similar way of what is currently done
for comparing SRIOV interfaces (from database) to ports (from device).

Closes-bug: 1927089
Signed-off-by: Douglas Henrique Koerich <douglashenrique.koerich@windriver.com>
Change-Id: I380bd66a8229a72ef1981cbefa3a0543c28d7f30
This commit is contained in:
Douglas Henrique Koerich 2021-05-14 14:45:29 -04:00
parent ed967ad81c
commit 9d8cdc5bb3
4 changed files with 40 additions and 42 deletions

View File

@ -3397,29 +3397,38 @@ class HostController(rest.RestController):
dev.pdevice_id not in device.SRIOV_ENABLED_FEC_DEVICE_IDS): dev.pdevice_id not in device.SRIOV_ENABLED_FEC_DEVICE_IDS):
return return
if (dev.extra_info and try:
dev.extra_info.endswith(device.DEVICE_APPLY_PENDING)): sriov_numvfs = int(dev.sriov_numvfs)
msg = (_("Pending configuration of FEC device. " except TypeError:
"Please wait a few minutes for inventory update and " sriov_numvfs = 0
"retry host-unlock."))
LOG.info(msg)
pecan.request.rpcapi.update_sriov_config(
pecan.request.context,
host['uuid'])
raise wsme.exc.ClientSideError(msg)
sriov_numvfs = dev.sriov_numvfs if dev.extra_info:
if not sriov_numvfs: extra_info = ast.literal_eval(dev.extra_info)
return expected_numvfs = int(extra_info['expected_numvfs'])
if (dev.sriov_vfs_pci_address and if sriov_numvfs != expected_numvfs:
sriov_numvfs == len(dev.sriov_vfs_pci_address.split(','))): msg = (_("Expecting sriov_numvfs=%d for FEC device pciaddr=%s. "
"Please wait a few minutes for inventory update and "
"retry host-unlock." % (expected_numvfs, dev.pciaddr)))
LOG.info(msg)
pecan.request.rpcapi.update_sriov_config(
pecan.request.context,
host['uuid'])
raise wsme.exc.ClientSideError(msg)
if not dev.sriov_vfs_pci_address or len(dev.sriov_vfs_pci_address) == 0:
sriov_vfs_pci_address = []
else:
sriov_vfs_pci_address = dev.sriov_vfs_pci_address.split(',')
if sriov_numvfs == len(sriov_vfs_pci_address):
if sriov_numvfs > 0:
LOG.info("check sriov_numvfs=%s sriov_vfs_pci_address=%s" % LOG.info("check sriov_numvfs=%s sriov_vfs_pci_address=%s" %
(sriov_numvfs, dev.sriov_vfs_pci_address)) (sriov_numvfs, dev.sriov_vfs_pci_address))
else: else:
msg = (_("Expecting number of FEC device sriov_numvfs=%s. " msg = (_("Expecting sriov_vfs_pci_address length=%d for FEC "
"Please wait a few minutes for inventory update and " "device pciaddr=%s. Please wait a few minutes for "
"retry host-unlock." % "inventory update and retry host-unlock." %
sriov_numvfs)) (sriov_numvfs, dev.pciaddr)))
LOG.info(msg) LOG.info(msg)
pecan.request.rpcapi.update_sriov_config( pecan.request.rpcapi.update_sriov_config(
pecan.request.context, pecan.request.context,

View File

@ -9,6 +9,7 @@ from pecan import rest
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan import wsmeext.pecan as wsme_pecan
from ast import literal_eval
from oslo_log import log from oslo_log import log
from sysinv._i18n import _ from sysinv._i18n import _
@ -327,13 +328,16 @@ class PCIDeviceController(rest.RestController):
rpc_device[field] = None rpc_device[field] = None
else: else:
rpc_device[field] = getattr(device, field) rpc_device[field] = getattr(device, field)
if field == 'sriov_numvfs':
if sriov_update: # Save desired number of VFs in extra_info since
# Set indication of pending configuration (runtime manifest apply) # sriov_numvfs may get overwritten by concurrent inventory report
# for this device expected_numvfs = {'expected_numvfs': rpc_device[field]}
if not rpc_device['extra_info']: if not rpc_device['extra_info']:
rpc_device['extra_info'] = '' rpc_device['extra_info'] = str(expected_numvfs)
rpc_device['extra_info'] += dconstants.DEVICE_APPLY_PENDING else:
extra_info = literal_eval(rpc_device['extra_info'])
extra_info.update(expected_numvfs)
rpc_device['extra_info'] = str(extra_info)
rpc_device.save() rpc_device.save()
@ -355,7 +359,7 @@ def _check_host(host):
def _check_field(field): def _check_field(field):
if field not in ["enabled", "name", "driver", "sriov_numvfs", "sriov_vf_driver"]: if field not in ["enabled", "name", "driver", "sriov_numvfs", "sriov_vf_driver", "extra_info"]:
raise wsme.exc.ClientSideError(_('Modifying %s attribute restricted') % field) raise wsme.exc.ClientSideError(_('Modifying %s attribute restricted') % field)

View File

@ -89,6 +89,3 @@ DEVICE_IMAGE_UPDATE_NULL = ''
# Device Image Action # Device Image Action
APPLY_ACTION = 'apply' APPLY_ACTION = 'apply'
REMOVE_ACTION = 'remove' REMOVE_ACTION = 'remove'
# Device Configuration Status
DEVICE_APPLY_PENDING = '/APPLYING'

View File

@ -2804,18 +2804,6 @@ class ConductorManager(service.PeriodicService):
'extra_info': dev.get('extra_info', None)} 'extra_info': dev.get('extra_info', None)}
LOG.info("attr: %s" % attr) LOG.info("attr: %s" % attr)
if attr['extra_info']:
extra_info = attr['extra_info']
# TODO: Change 'extra_info' to be a string representation
# of a dictionary, embedding the desired (requested) #VFs
# along with the APPLYING flag
# Get rid of indication of pending configuration, if any
if extra_info.endswith(dconstants.DEVICE_APPLY_PENDING):
attr['extra_info'] = extra_info[:extra_info.find(
dconstants.DEVICE_APPLY_PENDING)]
if (host['administrative'] == constants.ADMIN_LOCKED if (host['administrative'] == constants.ADMIN_LOCKED
and pci_dev['pdevice_id'] in and pci_dev['pdevice_id'] in
dconstants.SRIOV_ENABLED_FEC_DEVICE_IDS): dconstants.SRIOV_ENABLED_FEC_DEVICE_IDS):