binman: Detect when valid images are not produced
When external blobs are missing, show a message indicating that the images are not functional. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
f9793a12c5
commit
13262c9362
@ -403,6 +403,9 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
|
|||||||
allow_resize: True to allow entries to change size (this does a re-pack
|
allow_resize: True to allow entries to change size (this does a re-pack
|
||||||
of the entries), False to raise an exception
|
of the entries), False to raise an exception
|
||||||
allow_missing: Allow blob_ext objects to be missing
|
allow_missing: Allow blob_ext objects to be missing
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if one or more external blobs are missing, False if all are present
|
||||||
"""
|
"""
|
||||||
if get_contents:
|
if get_contents:
|
||||||
image.SetAllowMissing(allow_missing)
|
image.SetAllowMissing(allow_missing)
|
||||||
@ -450,6 +453,12 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
|
|||||||
image.BuildImage()
|
image.BuildImage()
|
||||||
if write_map:
|
if write_map:
|
||||||
image.WriteMap()
|
image.WriteMap()
|
||||||
|
missing_list = []
|
||||||
|
image.CheckMissing(missing_list)
|
||||||
|
if missing_list:
|
||||||
|
tout.Warning("Image '%s' is missing external blobs and is non-functional: %s" %
|
||||||
|
(image.name, ' '.join([e.name for e in missing_list])))
|
||||||
|
return bool(missing_list)
|
||||||
|
|
||||||
|
|
||||||
def Binman(args):
|
def Binman(args):
|
||||||
@ -524,14 +533,17 @@ def Binman(args):
|
|||||||
|
|
||||||
images = PrepareImagesAndDtbs(dtb_fname, args.image,
|
images = PrepareImagesAndDtbs(dtb_fname, args.image,
|
||||||
args.update_fdt)
|
args.update_fdt)
|
||||||
|
missing = False
|
||||||
for image in images.values():
|
for image in images.values():
|
||||||
ProcessImage(image, args.update_fdt, args.map,
|
missing |= ProcessImage(image, args.update_fdt, args.map,
|
||||||
allow_missing=args.allow_missing)
|
allow_missing=args.allow_missing)
|
||||||
|
|
||||||
# Write the updated FDTs to our output files
|
# Write the updated FDTs to our output files
|
||||||
for dtb_item in state.GetAllFdts():
|
for dtb_item in state.GetAllFdts():
|
||||||
tools.WriteFile(dtb_item._fname, dtb_item.GetContents())
|
tools.WriteFile(dtb_item._fname, dtb_item.GetContents())
|
||||||
|
|
||||||
|
if missing:
|
||||||
|
tout.Warning("Some images are invalid")
|
||||||
finally:
|
finally:
|
||||||
tools.FinaliseOutputDir()
|
tools.FinaliseOutputDir()
|
||||||
finally:
|
finally:
|
||||||
|
@ -84,6 +84,7 @@ class Entry(object):
|
|||||||
self.image_pos = None
|
self.image_pos = None
|
||||||
self._expand_size = False
|
self._expand_size = False
|
||||||
self.compress = 'none'
|
self.compress = 'none'
|
||||||
|
self.missing = False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def Lookup(node_path, etype):
|
def Lookup(node_path, etype):
|
||||||
@ -803,3 +804,14 @@ features to produce new behaviours.
|
|||||||
"""
|
"""
|
||||||
# This is meaningless for anything other than sections
|
# This is meaningless for anything other than sections
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def CheckMissing(self, missing_list):
|
||||||
|
"""Check if any entries in this section have missing external blobs
|
||||||
|
|
||||||
|
If there are missing blobs, the entries are added to the list
|
||||||
|
|
||||||
|
Args:
|
||||||
|
missing_list: List of Entry objects to be added to
|
||||||
|
"""
|
||||||
|
if self.missing:
|
||||||
|
missing_list.append(self)
|
||||||
|
@ -34,5 +34,6 @@ class Entry_blob_ext(Entry_blob):
|
|||||||
# Allow the file to be missing
|
# Allow the file to be missing
|
||||||
if not self._pathname:
|
if not self._pathname:
|
||||||
self.SetContents(b'')
|
self.SetContents(b'')
|
||||||
|
self.missing = True
|
||||||
return True
|
return True
|
||||||
return super().ObtainContents()
|
return super().ObtainContents()
|
||||||
|
@ -55,6 +55,7 @@ class Entry_section(Entry):
|
|||||||
self._skip_at_start = None
|
self._skip_at_start = None
|
||||||
self._end_4gb = False
|
self._end_4gb = False
|
||||||
self._allow_missing = False
|
self._allow_missing = False
|
||||||
|
self.missing = False
|
||||||
|
|
||||||
def ReadNode(self):
|
def ReadNode(self):
|
||||||
"""Read properties from the image node"""
|
"""Read properties from the image node"""
|
||||||
@ -559,3 +560,14 @@ class Entry_section(Entry):
|
|||||||
True if allowed, False if not allowed
|
True if allowed, False if not allowed
|
||||||
"""
|
"""
|
||||||
return self._allow_missing
|
return self._allow_missing
|
||||||
|
|
||||||
|
def CheckMissing(self, missing_list):
|
||||||
|
"""Check if any entries in this section have missing external blobs
|
||||||
|
|
||||||
|
If there are missing blobs, the entries are added to the list
|
||||||
|
|
||||||
|
Args:
|
||||||
|
missing_list: List of Entry objects to be added to
|
||||||
|
"""
|
||||||
|
for entry in self._entries.values():
|
||||||
|
entry.CheckMissing(missing_list)
|
||||||
|
@ -3380,7 +3380,19 @@ class TestFunctional(unittest.TestCase):
|
|||||||
|
|
||||||
def testExtblobMissingOk(self):
|
def testExtblobMissingOk(self):
|
||||||
"""Test an image with an missing external blob that is allowed"""
|
"""Test an image with an missing external blob that is allowed"""
|
||||||
self._DoTestFile('158_blob_ext_missing.dts', allow_missing=True)
|
with test_util.capture_sys_output() as (stdout, stderr):
|
||||||
|
self._DoTestFile('158_blob_ext_missing.dts', allow_missing=True)
|
||||||
|
err = stderr.getvalue()
|
||||||
|
self.assertRegex(err, "Image 'main-section'.*missing.*: blob-ext")
|
||||||
|
|
||||||
|
def testExtblobMissingOkSect(self):
|
||||||
|
"""Test an image with an missing external blob that is allowed"""
|
||||||
|
with test_util.capture_sys_output() as (stdout, stderr):
|
||||||
|
self._DoTestFile('159_blob_ext_missing_sect.dts',
|
||||||
|
allow_missing=True)
|
||||||
|
err = stderr.getvalue()
|
||||||
|
self.assertRegex(err, "Image 'main-section'.*missing.*: "
|
||||||
|
"blob-ext blob-ext2")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
23
tools/binman/test/159_blob_ext_missing_sect.dts
Normal file
23
tools/binman/test/159_blob_ext_missing_sect.dts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
binman {
|
||||||
|
size = <0x80>;
|
||||||
|
|
||||||
|
section {
|
||||||
|
blob-ext {
|
||||||
|
filename = "missing-file";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
blob-ext2 {
|
||||||
|
type = "blob-ext";
|
||||||
|
filename = "missing-file2";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -171,6 +171,7 @@ def Init(_verbose=WARNING, stdout=sys.stdout):
|
|||||||
|
|
||||||
# TODO(sjg): Move this into Chromite libraries when we have them
|
# TODO(sjg): Move this into Chromite libraries when we have them
|
||||||
stdout_is_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
|
stdout_is_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
|
||||||
|
stderr_is_tty = hasattr(sys.stderr, 'isatty') and sys.stderr.isatty()
|
||||||
|
|
||||||
def Uninit():
|
def Uninit():
|
||||||
ClearProgress()
|
ClearProgress()
|
||||||
|
Loading…
Reference in New Issue
Block a user