]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
binman: Put fake files in a subdirectory
authorSimon Glass <sjg@chromium.org>
Sun, 7 Aug 2022 15:46:46 +0000 (09:46 -0600)
committerSimon Glass <sjg@chromium.org>
Sun, 21 Aug 2022 00:07:32 +0000 (18:07 -0600)
At present fake files from a previous build appear to be real files for
a subsequent build, since they sit in the output directory.

This can cause problems, since binman may need to parse the file, e.g.
with the Intel description.bin files.

Fix this by putting them in a 'binman-fake' subdirectory. Keep a track
of the fake filename so we only create it once. Subsequent builds will
still see that the file is missing and mark it as fake.

Update a few tests to check the behaviour.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/binman/binman.rst
tools/binman/control.py
tools/binman/entry.py
tools/binman/ftest.py

index 6e1fd3476f17dc31191ee59488676552e4dd43ed..f94fd7e2a53c0ed9b5eb8bed6e748c71dad5421a 100644 (file)
@@ -1684,8 +1684,6 @@ Some ideas:
 - Figure out how to make Fdt support changing the node order, so that
   Node.AddSubnode() can support adding a node before another, existing node.
   Perhaps it should completely regenerate the flat tree?
-- Put faked files into a separate subdir and remove them on start-up, to avoid
-  seeing them as 'real' files on a subsequent run
 
 --
 Simon Glass <sjg@chromium.org>
index ce57dc7efc7bf69ee160bc067666ce83fc377b9e..8eea864d45bcf2b7d70cd2d1978cf6de7953bafd 100644 (file)
@@ -16,8 +16,9 @@ from patman import tools
 
 from binman import bintool
 from binman import cbfs_util
-from binman import elf
 from patman import command
+from binman import elf
+from binman import entry
 from patman import tout
 
 # These are imported if needed since they import libfdt
@@ -717,6 +718,13 @@ def Binman(args):
             bintool.Bintool.set_missing_list(
                 args.force_missing_bintools.split(',') if
                 args.force_missing_bintools else None)
+
+            # Create the directory here instead of Entry.check_fake_fname()
+            # since that is called from a threaded context so different threads
+            # may race to create the directory
+            if args.fake_ext_blobs:
+                entry.Entry.create_fake_dir()
+
             for image in images.values():
                 invalid |= ProcessImage(image, args.update_fdt, args.map,
                                        allow_missing=args.allow_missing,
index e3767aefa737d22726ee7dc7f09d99614eb40172..28a75109900f41db91e06886b5e261dbc2cc6e17 100644 (file)
@@ -9,6 +9,7 @@ import importlib
 import os
 import pathlib
 import sys
+import time
 
 from binman import bintool
 from binman import comp_util
@@ -82,7 +83,10 @@ class Entry(object):
         missing_bintools: List of missing bintools for this entry
         update_hash: True if this entry's "hash" subnode should be
             updated with a hash of the entry contents
+        fake_fname: Fake filename, if one was created, else None
     """
+    fake_dir = None
+
     def __init__(self, section, etype, node, name_prefix=''):
         # Put this here to allow entry-docs and help to work without libfdt
         global state
@@ -116,6 +120,7 @@ class Entry(object):
         self.bintools = {}
         self.missing_bintools = []
         self.update_hash = True
+        self.fake_fname = None
 
     @staticmethod
     def FindEntryClass(etype, expanded):
@@ -1014,12 +1019,14 @@ features to produce new behaviours.
                 bool: True if the blob was faked, False if not
         """
         if self.allow_fake and not pathlib.Path(fname).is_file():
-            outfname = tools.get_output_filename(os.path.basename(fname))
-            with open(outfname, "wb") as out:
-                out.truncate(size)
+            if not self.fake_fname:
+                outfname = os.path.join(self.fake_dir, os.path.basename(fname))
+                with open(outfname, "wb") as out:
+                    out.truncate(size)
+                tout.info(f"Entry '{self._node.path}': Faked blob '{outfname}'")
+                self.fake_fname = outfname
             self.faked = True
-            tout.info(f"Entry '{self._node.path}': Faked file '{outfname}'")
-            return outfname, True
+            return self.fake_fname, True
         return fname, False
 
     def CheckFakedBlobs(self, faked_blobs_list):
@@ -1169,3 +1176,11 @@ features to produce new behaviours.
         fname = tools.get_output_filename(f'{prefix}.{uniq}')
         tools.write_file(fname, data)
         return data, fname, uniq
+
+    @classmethod
+    def create_fake_dir(cls):
+        """Create the directory for fake files"""
+        cls.fake_dir = tools.get_output_filename('binman-fake')
+        if not os.path.exists(cls.fake_dir):
+            os.mkdir(cls.fake_dir)
+        tout.notice(f"Fake-blob dir is '{cls.fake_dir}'")
index fa1f421c052165f78d744cf5e8c89e750ae9d511..c8bab5c941612a9b866516ff5c71b532d725ab1a 100644 (file)
@@ -5453,7 +5453,16 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
             err)
 
     def checkFitSplitElf(self, **kwargs):
-        """Test an split-elf FIT with a missing ELF file"""
+        """Test an split-elf FIT with a missing ELF file
+
+        Args:
+            kwargs (dict of str): Arguments to pass to _DoTestFile()
+
+        Returns:
+            tuple:
+                str: stdout result
+                str: stderr result
+        """
         entry_args = {
             'of-list': 'test-fdt1 test-fdt2',
             'default-dt': 'test-fdt2',
@@ -5464,23 +5473,32 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
         with test_util.capture_sys_output() as (stdout, stderr):
             self._DoTestFile(
                 '226_fit_split_elf.dts', entry_args=entry_args,
-                extra_indirs=[test_subdir], **kwargs)
-        err = stderr.getvalue()
-        return err
+                extra_indirs=[test_subdir], verbosity=3, **kwargs)
+            out = stdout.getvalue()
+            err = stderr.getvalue()
+        return out, err
 
     def testFitSplitElfMissing(self):
         """Test an split-elf FIT with a missing ELF file"""
-        err = self.checkFitSplitElf(allow_missing=True)
+        out, err = self.checkFitSplitElf(allow_missing=True)
         self.assertRegex(
             err,
             "Image '.*' is missing external blobs and is non-functional: .*")
+        self.assertNotRegex(out, '.*Faked blob.*')
+        fname = tools.get_output_filename('binman-fake/missing.elf')
+        self.assertFalse(os.path.exists(fname))
 
     def testFitSplitElfFaked(self):
         """Test an split-elf FIT with faked ELF file"""
-        err = self.checkFitSplitElf(allow_missing=True, allow_fake_blobs=True)
+        out, err = self.checkFitSplitElf(allow_missing=True, allow_fake_blobs=True)
         self.assertRegex(
             err,
             "Image '.*' is missing external blobs and is non-functional: .*")
+        self.assertRegex(
+            out,
+            "Entry '/binman/fit/images/@tee-SEQ/tee-os': Faked blob '.*binman-fake/missing.elf")
+        fname = tools.get_output_filename('binman-fake/missing.elf')
+        self.assertTrue(os.path.exists(fname))
 
     def testPreLoad(self):
         """Test an image with a pre-load header"""