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.

Reply via email to