This also enables probing for a configuration type. Signed-off-by: Andrej Utz <andrej....@st.oth-regensburg.de> --- pyjailhouse/config_parser.py | 99 +++++++++++++++++++----------------- tools/jailhouse-config-check | 5 +- 2 files changed, 56 insertions(+), 48 deletions(-)
diff --git a/pyjailhouse/config_parser.py b/pyjailhouse/config_parser.py index a45aa7d7..2b47d9b6 100644 --- a/pyjailhouse/config_parser.py +++ b/pyjailhouse/config_parser.py @@ -197,8 +197,9 @@ class CellConfig(CStruct): '_pci_devices', '_pci_caps', '_stream_ids', \ 'vpci_irq_base', 'cpu_reset_address', _BIN_FIELD_NUM = len(__slots__) - _BIN_FMT_HDR = struct.Struct('=6sH') _BIN_FMT = struct.Struct('=32s4xIIIIIIIIIIQ8x32x') + _BIN_FMT_HDR = struct.Struct('=6sH') + _BIN_SIGNATURE = b'JHCELL' def __init__(self): self.name = "" @@ -209,38 +210,27 @@ class CellConfig(CStruct): self.cpu_reset_address = 0 @classmethod - def parse(cls, stream, root_cell=False): - try: - if not root_cell: - (signature, revision) = cls._BIN_FMT_HDR.unpack_from( - stream.read(cls._BIN_FMT_HDR.size)) - if signature != b'JHCELL': - raise RuntimeError('Not a cell configuration') - if revision != _CONFIG_REVISION: - raise RuntimeError('Configuration file revision mismatch') - - self = cls.parse_class(cls, stream) - self.name = self.name.decode().strip('\0') - stream.seek(self._cpu_sets, io.SEEK_CUR) # skip CPU set - - self.memory_regions = \ - cls.parse_array(MemRegion, self.memory_regions, stream) - self.cache_regions = \ - cls.parse_array(CacheRegion, self.cache_regions, stream) - self.irqchips = cls.parse_array(Irqchip, self.irqchips, stream) - self.pio_regions = \ - cls.parse_array(PIORegion, self.pio_regions, stream) - - return self - except struct.error: - raise RuntimeError('Not a %scell configuration' % - ('root ' if root_cell else '')) + def parse(cls, stream): + self = cls.parse_class(cls, stream) + self.name = self.name.decode().strip('\0') + stream.seek(self._cpu_sets, io.SEEK_CUR) # skip CPU set + + self.memory_regions = \ + cls.parse_array(MemRegion, self.memory_regions, stream) + self.cache_regions = \ + cls.parse_array(CacheRegion, self.cache_regions, stream) + self.irqchips = cls.parse_array(Irqchip, self.irqchips, stream) + self.pio_regions = \ + cls.parse_array(PIORegion, self.pio_regions, stream) + + return self class SystemConfig(CStruct): _BIN_FMT = struct.Struct('=4x') # ...followed by MemRegion as hypervisor memory _BIN_FMT_CONSOLE_AND_PLATFORM = struct.Struct('32x12x224x44x') + _BIN_SIGNATURE = b'JHSYST' # constructed fields __slots__ = 'hypervisor_memory', 'root_cell', @@ -251,22 +241,39 @@ class SystemConfig(CStruct): @classmethod def parse(cls, stream): - try: - hdr_fmt = CellConfig._BIN_FMT_HDR - (signature, revision) = \ - hdr_fmt.unpack_from(stream.read(hdr_fmt.size)) - if signature != b'JHSYST': - raise RuntimeError('Not a root cell configuration') - if revision != _CONFIG_REVISION: - raise RuntimeError('Configuration file revision mismatch') - - self = cls.parse_class(cls, stream) - self.hypervisor_memory = MemRegion.parse(stream) - - offs = cls._BIN_FMT_CONSOLE_AND_PLATFORM.size - offs += hdr_fmt.size # skip header inside rootcell - stream.seek(offs, io.SEEK_CUR) - self.root_cell = CellConfig.parse(stream, True) - return self - except struct.error: - raise RuntimeError('Not a root cell configuration') + self = cls.parse_class(cls, stream) + self.hypervisor_memory = MemRegion.parse(stream) + + offs = cls._BIN_FMT_CONSOLE_AND_PLATFORM.size + offs += CellConfig._BIN_FMT_HDR.size # skip header inside rootcell + stream.seek(offs, io.SEEK_CUR) + self.root_cell = CellConfig.parse(stream) + return self + + +def parse(stream, config_expect=None): + fmt = CellConfig._BIN_FMT_HDR + + try: + (signature, revision) = fmt.unpack_from(stream.read(fmt.size)) + except struct.error: + raise RuntimeError('Not a Jailhouse configuration') + + if config_expect == None: + # Try probing + if signature == CellConfig._BIN_SIGNATURE: + config_expect = CellConfig + elif signature == SystemConfig._BIN_SIGNATURE: + config_expect = SystemConfig + else: + raise RuntimeError('Not a Jailhouse configuration') + elif config_expect._BIN_SIGNATURE != signature: + raise RuntimeError("Not a '%s' configuration" % config_expect.__name__) + + if revision != _CONFIG_REVISION: + raise RuntimeError('Configuration file revision mismatch') + + try: + return config_expect.parse(stream) + except struct.error: + raise RuntimeError('Configuration unreadable') diff --git a/tools/jailhouse-config-check b/tools/jailhouse-config-check index 642e4fab..380f4a77 100755 --- a/tools/jailhouse-config-check +++ b/tools/jailhouse-config-check @@ -44,18 +44,19 @@ except IOError as e: print("Reading configuration set:") try: - sysconfig = config_parser.SystemConfig.parse(args.syscfg) + sysconfig = config_parser.parse(args.syscfg, config_parser.SystemConfig) root_cell = sysconfig.root_cell except RuntimeError as e: print(str(e) + ": " + args.syscfg.name, file=sys.stderr) exit(1) + cells = [root_cell] print(" Root cell: %s (%s)" % (root_cell.name, args.syscfg.name)) non_root_cells = [] for cfg in args.cellcfgs: try: - cell = config_parser.CellConfig.parse(cfg) + cell = config_parser.parse(cfg, config_parser.CellConfig) except RuntimeError as e: print(str(e) + ": " + cfg.name, file=sys.stderr) exit(1) -- 2.27.0 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to jailhouse-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/jailhouse-dev/20200630064228.4742-7-andrej.utz%40st.oth-regensburg.de.