config_tools/schema: add example data checks

This patch introduces the XML schema `datachecks.xsd` which is the central
place to specify and check assumptions on board characteristics and
scenario settings. Each assumption is expressed as an XSD assertion with
annotation of error severity (e.g. info, warning or error) and detailed
descriptions.

At compile time, the board and scenario XMLs are combined (by putting the
children of the root node together) can checked against the
schema. Assertion failures are categorized according to the defined
severity. Currently only errors will block compilation by outputing the
descriptions of the violated assertions.

The objective of this patch is the introduce the framework to document,
manage and check assumptions. A better way to present assumption violations
to end users (either on the command line or in the configuration editor) is
out of the scope of this series and will be considered in the future.

Tracked-On: #5922
Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
Junjie Mao 2021-05-05 11:17:16 +08:00 committed by wenlingz
parent 0aa899271d
commit 6ba4ac58cd
4 changed files with 87 additions and 5 deletions

View File

@ -17,6 +17,7 @@ ACRN_CONFIG_TARGET = ''
SOURCE_ROOT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../../')
HV_LICENSE_FILE = SOURCE_ROOT_DIR + 'misc/config_tools/library/hypervisor_license'
SCENARIO_SCHEMA_FILE = SOURCE_ROOT_DIR + 'misc/config_tools/schema/config.xsd'
DATACHECK_SCHEMA_FILE = SOURCE_ROOT_DIR + 'misc/config_tools/schema/datachecks.xsd'
PY_CACHES = ["__pycache__", "../board_config/__pycache__", "../scenario_config/__pycache__"]

View File

@ -24,6 +24,11 @@ import board_defconfig
from hv_item import HvInfo
import asl_gen
try:
import xmlschema
except ImportError:
pass
ACRN_PATH = common.SOURCE_ROOT_DIR
ACRN_CONFIG_DEF = ACRN_PATH + 'misc/config_tools/data/'
GEN_FILE = ["vm_configurations.h", "vm_configurations.c", "pci_dev.c", ".config", "ivshmem_cfg.h", "pt_intx.c"]
@ -97,10 +102,6 @@ def validate_scenario_schema(scenario_info):
:param xsd_doc: scenario schema
:param scenario_info: scenario file
"""
try:
import xmlschema
except ImportError:
return
"""
XMLSchema does not process XInclude.
@ -129,13 +130,36 @@ def validate_scenario_schema(scenario_info):
reason = validation_error.reason + ": last call: " + str(validation_error.obj)
scenario_cfg_lib.ERR_LIST[key] = element + reason
def apply_data_checks(board_info, scenario_info):
xsd_doc = etree.parse(common.DATACHECK_SCHEMA_FILE)
xsd_doc.xinclude()
datachecks_schema = xmlschema.XMLSchema11(etree.tostring(xsd_doc, encoding="unicode"))
main_etree = etree.parse(board_info)
scenario_etree = etree.parse(scenario_info)
main_etree.getroot().extend(scenario_etree.getroot()[:])
# FIXME: Figure out proper error keys for data check failures
error_key = ""
it = datachecks_schema.iter_errors(main_etree)
for idx, error in enumerate(it, start=1):
anno = error.validator.annotation
description = anno.documentation[0].text
severity = anno.elem.get("{https://projectacrn.org}severity")
if severity == "error":
if error_key in scenario_cfg_lib.ERR_LIST.keys():
scenario_cfg_lib.ERR_LIST[error_key].append("\n" + description)
else:
scenario_cfg_lib.ERR_LIST[error_key] = description
def validate_scenario_setting(board_info, scenario_info):
hv_cfg_lib.ERR_LIST = {}
scenario_cfg_lib.ERR_LIST = {}
validate_scenario_schema(scenario_info)
if "xmlschema" in sys.modules.keys():
validate_scenario_schema(scenario_info)
apply_data_checks(board_info, scenario_info)
"""
Validate settings in scenario xml

View File

@ -0,0 +1,39 @@
<?xml version="1.0"?>
<xs:schema xml:id="root"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:acrn="https://projectacrn.org">
<xs:assert test="every $cpu in vm/cpu_affinity/pcpu_id satisfies count(processors//thread[cpu_id = $cpu]) = 1">
<xs:annotation acrn:severity="warning">
<xs:documentation>The physical CPUs allocated to VMs shall exist on the target board.
This assertion checks that the physical CPUs that are explicitly allocated to VMs do exist on the target board. Failures
in meeting this assertion may cause the following.
- The hypervisor may access wrong per CPU regions, leading to random memory corruption.
- A VM may failed wake (by sending INIT-SIPI-SIPI IPIs) all the vCPUs allocated to it.
To fix this error, you can
- In the board XML, check whether all physical CPUs are encoded under the processors/ node. When generating the board
XML on the target board, make sure the native OS has not make any CPU offline.
- In the scenario XML, check whether the allocated CPUs are specified using consecutive integers starting from 0, not
their APIC IDs or x2APIC IDs.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $vm in vm satisfies
every $cpu in $vm/cpu_affinity/pcpu_id satisfies
processors//thread[cpu_id = $cpu]/core_type = processors//thread[cpu_id = $vm/cpu_affinity/pcpu_id[1]]/core_type">
<xs:annotation acrn:severity="warning">
<xs:documentation>The physical CPUs allocated to the same VM shall have the same core types.
On platforms having both big and little cores, the current design of ACRN only allows allocating the same type of cores
to a pre-launched VM.
To fix this error, double check the allocation of physical CPUs to each pre-launched VM and ensure that only big cores
or little cores are assigned, but not both.</xs:documentation>
</xs:annotation>
</xs:assert>
</xs:schema>

View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<xs:schema
xmlns:xi="http://www.w3.org/2003/XInclude"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="acrn-config">
<xs:complexType>
<xs:sequence>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:anyAttribute processContents="skip"/>
<xi:include href="checks/pre_launched_vm_support.xsd" xpointer="xpointer(id('root')/*)" />
</xs:complexType>
</xs:element>
</xs:schema>