From: Tim Orling <[email protected]>

The get_depgraph() function hangs indefinitely when a layer causes
command failures (e.g. meta-virtualization) because:

1. bb.command.CommandFailed was not included in the event mask passed
   to set_event_mask(), so the failure event was silently dropped and
   the while True loop never received a terminating event.

2. There was no timeout handling for the case where wait_event()
   repeatedly returns None, leaving no escape from the loop.

Add CommandFailed to the event mask so failure events are properly
received and handled. Also add a timeout counter that raises
RuntimeError after 300 consecutive seconds of no events, preventing
an infinite hang.

Fixes [YOCTO #16170]

Signed-off-by: Tim Orling <[email protected]>
---
 scripts/lib/checklayer/__init__.py | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/scripts/lib/checklayer/__init__.py 
b/scripts/lib/checklayer/__init__.py
index 86aadf39a6..b70cef1b14 100644
--- a/scripts/lib/checklayer/__init__.py
+++ b/scripts/lib/checklayer/__init__.py
@@ -360,12 +360,15 @@ def get_depgraph(targets=['world'], failsafe=False):
     depgraph = None
     with bb.tinfoil.Tinfoil() as tinfoil:
         tinfoil.prepare(config_only=False)
-        tinfoil.set_event_mask(['bb.event.NoProvider', 
'bb.event.DepTreeGenerated', 'bb.command.CommandCompleted'])
+        tinfoil.set_event_mask(['bb.event.NoProvider', 
'bb.event.DepTreeGenerated', 'bb.command.CommandCompleted', 
'bb.command.CommandFailed'])
         if not tinfoil.run_command('generateDepTreeEvent', targets, 
'do_build'):
             raise RuntimeError('starting generateDepTreeEvent failed')
+        timeouts = 0
+        max_timeouts = 300
         while True:
             event = tinfoil.wait_event(timeout=1000)
             if event:
+                timeouts = 0
                 if isinstance(event, bb.command.CommandFailed):
                     raise RuntimeError('Generating dependency information 
failed: %s' % event.error)
                 elif isinstance(event, bb.command.CommandCompleted):
@@ -382,6 +385,10 @@ def get_depgraph(targets=['world'], failsafe=False):
                         raise RuntimeError('Nothing provides %s.' % 
(event._item))
                 elif isinstance(event, bb.event.DepTreeGenerated):
                     depgraph = event._depgraph
+            else:
+                timeouts += 1
+                if timeouts > max_timeouts:
+                    raise RuntimeError('Timed out waiting for dependency graph 
generation to complete after %d seconds' % max_timeouts)
 
     if depgraph is None:
         raise RuntimeError('Could not retrieve the depgraph.')
-- 
2.43.0

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#231171): 
https://lists.openembedded.org/g/openembedded-core/message/231171
Mute This Topic: https://lists.openembedded.org/mt/117830317/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to