* [PATCH 2/9] gnu-config: delete do_compile task
2023-12-14 13:45 [PATCH 1/9] oeqa/selftest/sstatetests: re-work CDN tests, add local cache tests Alexander Kanavin
@ 2023-12-14 13:45 ` Alexander Kanavin
2023-12-14 13:45 ` [PATCH 3/9] bitbake/runqueue: initialize RunQueueExecute before printdiff rather than after Alexander Kanavin
` (6 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-14 13:45 UTC (permalink / raw)
To: openembedded-core; +Cc: Alexander Kanavin
noexec flag has an unfortunate side effect of not writing out the .siginfo
file into sstate (because that is done in sstate bbclass
from a task-completed event handler).
In the absence of the siginfo file, diffsigs code is unable to trace back
the change in task signatures if the change is really basic and
affects tasks coming ahead of gnu-config-native:do_compile.
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
meta/recipes-devtools/gnu-config/gnu-config_git.bb | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/meta/recipes-devtools/gnu-config/gnu-config_git.bb b/meta/recipes-devtools/gnu-config/gnu-config_git.bb
index 718f798a00e..7c5a34db4e3 100644
--- a/meta/recipes-devtools/gnu-config/gnu-config_git.bb
+++ b/meta/recipes-devtools/gnu-config/gnu-config_git.bb
@@ -19,7 +19,8 @@ UPSTREAM_CHECK_COMMITS = "1"
CLEANBROKEN = "1"
-do_compile[noexec] = "1"
+deltask do_compile
+addtask install after do_configure
do_install () {
install -d ${D}${datadir}/gnu-config \
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 3/9] bitbake/runqueue: initialize RunQueueExecute before printdiff rather than after
2023-12-14 13:45 [PATCH 1/9] oeqa/selftest/sstatetests: re-work CDN tests, add local cache tests Alexander Kanavin
2023-12-14 13:45 ` [PATCH 2/9] gnu-config: delete do_compile task Alexander Kanavin
@ 2023-12-14 13:45 ` Alexander Kanavin
2023-12-14 14:39 ` [OE-core] " Richard Purdie
2023-12-14 13:45 ` [PATCH 4/9] bitbake/runqueue: rework 'bitbake -S printdiff' logic Alexander Kanavin
` (5 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-14 13:45 UTC (permalink / raw)
To: openembedded-core; +Cc: Alexander Kanavin
printdiff needs setscene dependencies and they're available only
through that object. Previously it was instantianted just after
running printdiff, this moves the initilization to just prior.
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
bitbake/lib/bb/runqueue.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 864708ee4a5..1f59d18b71a 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -1555,6 +1555,11 @@ class RunQueue:
('bb.event.HeartbeatEvent',), data=self.cfgData)
self.dm_event_handler_registered = True
+ self.rqdata.init_progress_reporter.next_stage()
+ self.start_worker()
+ self.rqdata.init_progress_reporter.next_stage()
+ self.rqexe = RunQueueExecute(self)
+
dump = self.cooker.configuration.dump_signatures
if dump:
self.rqdata.init_progress_reporter.finish()
@@ -1566,11 +1571,6 @@ class RunQueue:
self.state = runQueueComplete
if self.state is runQueueSceneInit:
- self.rqdata.init_progress_reporter.next_stage()
- self.start_worker()
- self.rqdata.init_progress_reporter.next_stage()
- self.rqexe = RunQueueExecute(self)
-
# If we don't have any setscene functions, skip execution
if not self.rqdata.runq_setscene_tids:
logger.info('No setscene tasks')
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [OE-core] [PATCH 3/9] bitbake/runqueue: initialize RunQueueExecute before printdiff rather than after
2023-12-14 13:45 ` [PATCH 3/9] bitbake/runqueue: initialize RunQueueExecute before printdiff rather than after Alexander Kanavin
@ 2023-12-14 14:39 ` Richard Purdie
2023-12-14 17:28 ` Alexander Kanavin
0 siblings, 1 reply; 14+ messages in thread
From: Richard Purdie @ 2023-12-14 14:39 UTC (permalink / raw)
To: Alexander Kanavin, openembedded-core; +Cc: Alexander Kanavin
On Thu, 2023-12-14 at 14:45 +0100, Alexander Kanavin wrote:
> printdiff needs setscene dependencies and they're available only
> through that object. Previously it was instantianted just after
> running printdiff, this moves the initilization to just prior.
>
> Signed-off-by: Alexander Kanavin <alex@linutronix.de>
> ---
> bitbake/lib/bb/runqueue.py | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
> index 864708ee4a5..1f59d18b71a 100644
> --- a/bitbake/lib/bb/runqueue.py
> +++ b/bitbake/lib/bb/runqueue.py
> @@ -1555,6 +1555,11 @@ class RunQueue:
> ('bb.event.HeartbeatEvent',), data=self.cfgData)
> self.dm_event_handler_registered = True
>
> + self.rqdata.init_progress_reporter.next_stage()
> + self.start_worker()
> + self.rqdata.init_progress_reporter.next_stage()
> + self.rqexe = RunQueueExecute(self)
> +
> dump = self.cooker.configuration.dump_signatures
> if dump:
> self.rqdata.init_progress_reporter.finish()
> @@ -1566,11 +1571,6 @@ class RunQueue:
> self.state = runQueueComplete
>
> if self.state is runQueueSceneInit:
> - self.rqdata.init_progress_reporter.next_stage()
> - self.start_worker()
> - self.rqdata.init_progress_reporter.next_stage()
> - self.rqexe = RunQueueExecute(self)
> -
> # If we don't have any setscene functions, skip execution
> if not self.rqdata.runq_setscene_tids:
> logger.info('No setscene tasks')
I not entirely happy about this since start_worker() executes processes
and isn't trivial. The code is careful enough to tear them down too at
exit but it is all a bit of a waste of time.
I had wondered if we can create RunQueueExecute() without the workers
but as the code stands, it does poke things into them in a small
isolated section. I think this code flow should be tweaked to stop
RunQueueExecute needing the workers to be started and that would be a
decent cleanup of the code anyway.
I can take a look at that if it helps since I think I've been moving
towards that refactor for a while anyway?
Cheers,
Richard
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [OE-core] [PATCH 3/9] bitbake/runqueue: initialize RunQueueExecute before printdiff rather than after
2023-12-14 14:39 ` [OE-core] " Richard Purdie
@ 2023-12-14 17:28 ` Alexander Kanavin
2023-12-15 16:04 ` Richard Purdie
0 siblings, 1 reply; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-14 17:28 UTC (permalink / raw)
To: Richard Purdie; +Cc: openembedded-core, Alexander Kanavin
On Thu, 14 Dec 2023 at 15:39, Richard Purdie
<richard.purdie@linuxfoundation.org> wrote:
> I not entirely happy about this since start_worker() executes processes
> and isn't trivial. The code is careful enough to tear them down too at
> exit but it is all a bit of a waste of time.
>
> I had wondered if we can create RunQueueExecute() without the workers
> but as the code stands, it does poke things into them in a small
> isolated section. I think this code flow should be tweaked to stop
> RunQueueExecute needing the workers to be started and that would be a
> decent cleanup of the code anyway.
>
> I can take a look at that if it helps since I think I've been moving
> towards that refactor for a while anyway?
Yes please. I haven't noticed any regression in printdiff performance,
other than a couple of additional lines printed, but if you can make a
better patch, that'd be welcome.
Meanwhile I'd like to implement what I mentioned in note (1) in patch
4/9, as it's a real regression that I realized only today as I was
preparing the patchset for submission and now it's bothering me :)
Alex
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [OE-core] [PATCH 3/9] bitbake/runqueue: initialize RunQueueExecute before printdiff rather than after
2023-12-14 17:28 ` Alexander Kanavin
@ 2023-12-15 16:04 ` Richard Purdie
2023-12-15 16:49 ` Alexander Kanavin
0 siblings, 1 reply; 14+ messages in thread
From: Richard Purdie @ 2023-12-15 16:04 UTC (permalink / raw)
To: Alexander Kanavin; +Cc: openembedded-core, Alexander Kanavin
On Thu, 2023-12-14 at 18:28 +0100, Alexander Kanavin wrote:
> On Thu, 14 Dec 2023 at 15:39, Richard Purdie
> <richard.purdie@linuxfoundation.org> wrote:
>
> > I not entirely happy about this since start_worker() executes processes
> > and isn't trivial. The code is careful enough to tear them down too at
> > exit but it is all a bit of a waste of time.
> >
> > I had wondered if we can create RunQueueExecute() without the workers
> > but as the code stands, it does poke things into them in a small
> > isolated section. I think this code flow should be tweaked to stop
> > RunQueueExecute needing the workers to be started and that would be a
> > decent cleanup of the code anyway.
> >
> > I can take a look at that if it helps since I think I've been moving
> > towards that refactor for a while anyway?
>
> Yes please. I haven't noticed any regression in printdiff performance,
> other than a couple of additional lines printed, but if you can make a
> better patch, that'd be welcome.
Patch on the bitbake list for this which removes more code than
it adds. We had already set everything up to do this :)
> Meanwhile I'd like to implement what I mentioned in note (1) in patch
> 4/9, as it's a real regression that I realized only today as I was
> preparing the patchset for submission and now it's bothering me :)
Yes, it is and I do agree we need to fix that.
Cheers,
Richard
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [OE-core] [PATCH 3/9] bitbake/runqueue: initialize RunQueueExecute before printdiff rather than after
2023-12-15 16:04 ` Richard Purdie
@ 2023-12-15 16:49 ` Alexander Kanavin
2023-12-15 16:56 ` Richard Purdie
0 siblings, 1 reply; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-15 16:49 UTC (permalink / raw)
To: Richard Purdie; +Cc: openembedded-core, Alexander Kanavin
On Fri, 15 Dec 2023 at 17:04, Richard Purdie
<richard.purdie@linuxfoundation.org> wrote:
> > Meanwhile I'd like to implement what I mentioned in note (1) in patch
> > 4/9, as it's a real regression that I realized only today as I was
> > preparing the patchset for submission and now it's bothering me :)
>
> Yes, it is and I do agree we need to fix that.
I just completed the fixing. It all works wonderfully in local builds,
but who knows what situations AB will be able to come up with :) It's
a bit crowded on the AB right now to start the tests there, so here
are the patches:
https://git.yoctoproject.org/poky-contrib/log/?h=akanavin/fix-printdiff
(I run the tests with a special contrib/kanavin/ branch of
autobuilder-helper that only runs the three needed selftests, and not
the whole gigantic set)
I also reverted the gnu-config tweak in that branch as it should be no
longer necessary.
I'll cherry-pick the bitbake patch before doing any further tests, but
it's now Friday evening, so anxiously watching ongoing selftests is
perhaps not the best idea.
Alex
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [OE-core] [PATCH 3/9] bitbake/runqueue: initialize RunQueueExecute before printdiff rather than after
2023-12-15 16:49 ` Alexander Kanavin
@ 2023-12-15 16:56 ` Richard Purdie
0 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2023-12-15 16:56 UTC (permalink / raw)
To: Alexander Kanavin; +Cc: openembedded-core, Alexander Kanavin
On Fri, 2023-12-15 at 17:49 +0100, Alexander Kanavin wrote:
> On Fri, 15 Dec 2023 at 17:04, Richard Purdie
> <richard.purdie@linuxfoundation.org> wrote:
>
> > > Meanwhile I'd like to implement what I mentioned in note (1) in patch
> > > 4/9, as it's a real regression that I realized only today as I was
> > > preparing the patchset for submission and now it's bothering me :)
> >
> > Yes, it is and I do agree we need to fix that.
>
> I just completed the fixing. It all works wonderfully in local builds,
> but who knows what situations AB will be able to come up with :) It's
> a bit crowded on the AB right now to start the tests there, so here
> are the patches:
> https://git.yoctoproject.org/poky-contrib/log/?h=akanavin/fix-printdiff
> (I run the tests with a special contrib/kanavin/ branch of
> autobuilder-helper that only runs the three needed selftests, and not
> the whole gigantic set)
Sounds good. I think we are getting to the bottom of some of the
underlying issues which is good and longer term should help usability a
lot.
> I also reverted the gnu-config tweak in that branch as it should be no
> longer necessary.
I was torn on that. I can drop from -next too.
> I'll cherry-pick the bitbake patch before doing any further tests, but
> it's now Friday evening, so anxiously watching ongoing selftests is
> perhaps not the best idea.
Fair enough! I've run that patch through local only testing so far, as
you say, the AB has a lot going on.
I've been torn on waiting for these or building M1 but I'm aiming for
just the CDN fix since this may or may not take a while to settle on
the autobuilder and I don't think we need any more pressure. The
failures are driving Alexandre a bit crazy in swatbot so getting things
sorted is important.
Cheers,
Richard
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/9] bitbake/runqueue: rework 'bitbake -S printdiff' logic
2023-12-14 13:45 [PATCH 1/9] oeqa/selftest/sstatetests: re-work CDN tests, add local cache tests Alexander Kanavin
2023-12-14 13:45 ` [PATCH 2/9] gnu-config: delete do_compile task Alexander Kanavin
2023-12-14 13:45 ` [PATCH 3/9] bitbake/runqueue: initialize RunQueueExecute before printdiff rather than after Alexander Kanavin
@ 2023-12-14 13:45 ` Alexander Kanavin
2023-12-14 13:45 ` [PATCH 5/9] selftest/sstatetests: fix up printdiff test to match rework of printdiff logic Alexander Kanavin
` (4 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-14 13:45 UTC (permalink / raw)
To: openembedded-core; +Cc: Alexander Kanavin
Previously printdiff code would iterate over tasks that were reported as invalid or absent,
trying to follow dependency chains that would reach the most basic invalid items in the tree.
While this works in tightly controlled local builds, it can lead to bizarre reports
against industrial-sized sstate caches, as the code would not consider whether the
overall target can be fulfilled from valid sstate objects, and instead report
missing sstate signature files that perhaps were never even created due to hash
equivalency providing shortcuts in builds.
This commit reworks the logic in two ways:
- start the iteration over final targets rather than missing objects
and stop at the first invalid object (1)
- if a given object can be fulfilled from sstate, recurse only into
its setscene dependencies; bitbake wouldn't care if dependencies
for the actual task are absent, and neither should printdiff
(1) there's a further improvement I'd like to make here: instead of
stopping, recurse into dependencies, with the goal of finding and reporting
the 'root' invalid objects. Otherwise tracking down the difference to its root
relies on finding the most 'recent' signature in stamps or sstate in a
different function later, and recursively comparing that to the current signature,
which is unreliable on real world caches. For the sake of fixing the test failures
I'd like to not delay the patchset any further for now.
[YOCTO #15289]
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
bitbake/lib/bb/runqueue.py | 29 ++++++++++++++---------------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 1f59d18b71a..61effe24fae 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -1717,35 +1717,34 @@ class RunQueue:
valid_new.add(dep)
invalidtasks = set()
- for tid in self.rqdata.runtaskentries:
- if tid not in valid_new and tid not in noexec:
- invalidtasks.add(tid)
- found = set()
- processed = set()
- for tid in invalidtasks:
+ toptasks = set(["{}:{}".format(t[3], t[2]) for t in self.rqdata.targets])
+ for tid in toptasks:
toprocess = set([tid])
while toprocess:
next = set()
for t in toprocess:
- for dep in self.rqdata.runtaskentries[t].depends:
- if dep in invalidtasks:
- found.add(tid)
- if dep not in processed:
- processed.add(dep)
+ if t not in valid_new and t not in noexec:
+ invalidtasks.add(t)
+ continue
+ if t in self.rqdata.runq_setscene_tids:
+ for dep in self.rqexe.sqdata.sq_deps[t]:
next.add(dep)
+ continue
+
+ for dep in self.rqdata.runtaskentries[t].depends:
+ next.add(dep)
+
toprocess = next
- if tid in found:
- toprocess = set()
tasklist = []
- for tid in invalidtasks.difference(found):
+ for tid in invalidtasks:
tasklist.append(tid)
if tasklist:
bb.plain("The differences between the current build and any cached tasks start at the following tasks:\n" + "\n".join(tasklist))
- return invalidtasks.difference(found)
+ return invalidtasks
def write_diffscenetasks(self, invalidtasks):
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 5/9] selftest/sstatetests: fix up printdiff test to match rework of printdiff logic
2023-12-14 13:45 [PATCH 1/9] oeqa/selftest/sstatetests: re-work CDN tests, add local cache tests Alexander Kanavin
` (2 preceding siblings ...)
2023-12-14 13:45 ` [PATCH 4/9] bitbake/runqueue: rework 'bitbake -S printdiff' logic Alexander Kanavin
@ 2023-12-14 13:45 ` Alexander Kanavin
2023-12-14 13:45 ` [PATCH 6/9] sstatesig/find_siginfo: unify a disjointed API Alexander Kanavin
` (3 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-14 13:45 UTC (permalink / raw)
To: openembedded-core; +Cc: Alexander Kanavin
The rework changes the console output significantly: where previously
printdiff would report the most basic invalid tasks it could find,
with this change the most top-level tasks are reported instead. This
is not a problem as diffsigs has its own task recursion facility, and will
track down the actual change anyway. However the changes still need to be reflected
in the selftests.
Note that printdiff is run on one specific target task rather than
overall do_build for a recipe. Otherwise find_siginfo would run
glob.glob("*/*/*taskname*") against autobuilder sstate cache for each
of those tasks (six or seven times) - this is an expensive operation
taking several minutes, and it's best to do it only once per test.
[YOCTO #15289]
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
.../perlcross_%.bbappend} | 0
meta/lib/oeqa/selftest/cases/sstatetests.py | 40 +++++++++----------
2 files changed, 18 insertions(+), 22 deletions(-)
rename meta-selftest/recipes-test/{quilt-native/quilt-native_%.bbappend => perlcross/perlcross_%.bbappend} (100%)
diff --git a/meta-selftest/recipes-test/quilt-native/quilt-native_%.bbappend b/meta-selftest/recipes-test/perlcross/perlcross_%.bbappend
similarity index 100%
rename from meta-selftest/recipes-test/quilt-native/quilt-native_%.bbappend
rename to meta-selftest/recipes-test/perlcross/perlcross_%.bbappend
diff --git a/meta/lib/oeqa/selftest/cases/sstatetests.py b/meta/lib/oeqa/selftest/cases/sstatetests.py
index f52ca77c09c..f5b3437d86b 100644
--- a/meta/lib/oeqa/selftest/cases/sstatetests.py
+++ b/meta/lib/oeqa/selftest/cases/sstatetests.py
@@ -824,14 +824,17 @@ TMPDIR = "${{TOPDIR}}/tmp-sstateprintdiff-difftmp-{}"
# Check if printdiff walks the full dependency chain from the image target to where the change is in a specific recipe
- def test_image_minimal_vs_quilt(self):
- expected_output = ("Task quilt-native:do_install couldn't be used from the cache because:",
+ def test_image_minimal_vs_perlcross(self):
+ expected_output = ("Task core-image-minimal:do_create_spdx couldn't be used from the cache because:",
"We need hash",
"most recent matching task was")
- expected_sametmp_output = expected_output + ("Variable do_install value changed",'+ echo "this changes the task signature"')
+ expected_sametmp_output = expected_output + (
+"Hash for task dependency perlcross-native:do_install changed from",
+"Variable do_install value changed",
+'+ echo "this changes the task signature"')
expected_difftmp_output = expected_output
- self.run_test_printdiff_changerecipe("core-image-minimal", "quilt-native", "-c do_install quilt-native",
+ self.run_test_printdiff_changerecipe("core-image-minimal:do_create_spdx", "perlcross", "-c do_install perlcross-native",
"""
do_install:append() {
echo "this changes the task signature"
@@ -843,15 +846,15 @@ expected_sametmp_output, expected_difftmp_output)
def test_gcc_runtime_vs_gcc_source(self):
gcc_source_pn = 'gcc-source-%s' % get_bb_vars(['PV'], 'gcc')['PV']
- expected_output = ("Task {}:do_preconfigure couldn't be used from the cache because:".format(gcc_source_pn),
+ expected_output = ("Task gcc-runtime:do_package_write_rpm couldn't be used from the cache because:",
"We need hash",
"most recent matching task was")
- expected_sametmp_output = expected_output + ("Variable do_preconfigure value changed",'+ print("this changes the task signature")')
- #FIXME: printdiff is supposed to find at least one preconfigure task signature in the sstate cache, but isn't able to
- #expected_difftmp_output = expected_output
- expected_difftmp_output = ()
+ expected_sametmp_output = expected_output + ("Hash for task dependency {}:do_preconfigure changed from".format(gcc_source_pn),
+"Variable do_preconfigure value changed",
+'+ print("this changes the task signature")')
+ expected_difftmp_output = expected_output
- self.run_test_printdiff_changerecipe("gcc-runtime", "gcc-source", "-c do_preconfigure {}".format(gcc_source_pn),
+ self.run_test_printdiff_changerecipe("gcc-runtime:do_package_write_rpm", "gcc-source", "-c do_preconfigure {}".format(gcc_source_pn),
"""
python do_preconfigure:append() {
print("this changes the task signature")
@@ -861,22 +864,15 @@ expected_sametmp_output, expected_difftmp_output)
# Check if changing a really base task definiton is reported against multiple core recipes using it
def test_image_minimal_vs_base_do_configure(self):
- expected_output = ("Task zstd-native:do_configure couldn't be used from the cache because:",
-"Task texinfo-dummy-native:do_configure couldn't be used from the cache because:",
-"Task ldconfig-native:do_configure couldn't be used from the cache because:",
-"Task gettext-minimal-native:do_configure couldn't be used from the cache because:",
-"Task tzcode-native:do_configure couldn't be used from the cache because:",
-"Task makedevs-native:do_configure couldn't be used from the cache because:",
-"Task pigz-native:do_configure couldn't be used from the cache because:",
-"Task update-rc.d-native:do_configure couldn't be used from the cache because:",
-"Task unzip-native:do_configure couldn't be used from the cache because:",
-"Task gnu-config-native:do_configure couldn't be used from the cache because:",
+ expected_output = ("Task core-image-minimal:do_populate_lic_deploy couldn't be used from the cache because:",
"We need hash",
"most recent matching task was")
- expected_sametmp_output = expected_output + ("Variable base_do_configure value changed",'+ echo "this changes base_do_configure() definiton "')
+ expected_sametmp_output = expected_output + ("Hash for task dependency gnu-config-native:do_configure changed from",
+"Variable base_do_configure value changed",
+'+ echo "this changes base_do_configure() definiton "')
expected_difftmp_output = expected_output
- self.run_test_printdiff_changeconfig("core-image-minimal",
+ self.run_test_printdiff_changeconfig("core-image-minimal:do_populate_lic_deploy",
"""
INHERIT += "base-do-configure-modified"
""",
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 6/9] sstatesig/find_siginfo: unify a disjointed API
2023-12-14 13:45 [PATCH 1/9] oeqa/selftest/sstatetests: re-work CDN tests, add local cache tests Alexander Kanavin
` (3 preceding siblings ...)
2023-12-14 13:45 ` [PATCH 5/9] selftest/sstatetests: fix up printdiff test to match rework of printdiff logic Alexander Kanavin
@ 2023-12-14 13:45 ` Alexander Kanavin
2023-12-14 13:45 ` [PATCH 7/9] bitbake-diffsigs/runqueue: adapt to reworked find_siginfo() Alexander Kanavin
` (2 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-14 13:45 UTC (permalink / raw)
To: openembedded-core; +Cc: Alexander Kanavin
find_siginfo() returns two different data structures depending
on whether its third argument (list of hashes to find) is empty or
not:
- a dict of timestamps keyed by path
- a dict of paths keyed by hash
This is not a good API design; it's much better to return
a dict of dicts that include both timestamp and path, keyed by
hash. Then the API consumer can decide how they want to use these
fields, particularly for additional diagnostics or informational
output.
I also took the opportunity to add a binary field that
tells if the match came from sstate or local stamps dir, which
will help prioritize local stamps when looking up most
recent task signatures.
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
meta/lib/oe/buildhistory_analysis.py | 2 +-
meta/lib/oe/sstatesig.py | 31 +++++++++------------
meta/lib/oeqa/selftest/cases/sstatetests.py | 10 +++----
3 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/meta/lib/oe/buildhistory_analysis.py b/meta/lib/oe/buildhistory_analysis.py
index b1856846b6a..4edad01580c 100644
--- a/meta/lib/oe/buildhistory_analysis.py
+++ b/meta/lib/oe/buildhistory_analysis.py
@@ -562,7 +562,7 @@ def compare_siglists(a_blob, b_blob, taskdiff=False):
elif not hash2 in hashfiles:
out.append("Unable to find matching sigdata for %s with hash %s" % (desc, hash2))
else:
- out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb, collapsed=True)
+ out2 = bb.siggen.compare_sigfiles(hashfiles[hash1]['path'], hashfiles[hash2]['path'], recursecb, collapsed=True)
for line in out2:
m = hashlib.sha256()
m.update(line.encode('utf-8'))
diff --git a/meta/lib/oe/sstatesig.py b/meta/lib/oe/sstatesig.py
index 8a97fb0c04b..0342bcdc87a 100644
--- a/meta/lib/oe/sstatesig.py
+++ b/meta/lib/oe/sstatesig.py
@@ -349,7 +349,6 @@ def find_siginfo(pn, taskname, taskhashlist, d):
pn, taskname = key.split(':', 1)
hashfiles = {}
- filedates = {}
def get_hashval(siginfo):
if siginfo.endswith('.siginfo'):
@@ -357,6 +356,12 @@ def find_siginfo(pn, taskname, taskhashlist, d):
else:
return siginfo.rpartition('.')[2]
+ def get_time(fullpath):
+ try:
+ return os.stat(fullpath).st_mtime
+ except OSError:
+ return None
+
# First search in stamps dir
localdata = d.createCopy()
localdata.setVar('MULTIMACH_TARGET_SYS', '*')
@@ -372,24 +377,21 @@ def find_siginfo(pn, taskname, taskhashlist, d):
filespec = '%s.%s.sigdata.*' % (stamp, taskname)
foundall = False
import glob
+ bb.debug(1, "Calling glob.glob on {}".format(filespec))
for fullpath in glob.glob(filespec):
match = False
if taskhashlist:
for taskhash in taskhashlist:
if fullpath.endswith('.%s' % taskhash):
- hashfiles[taskhash] = fullpath
+ hashfiles[taskhash] = {'path':fullpath, 'sstate':False, 'time':get_time(fullpath)}
if len(hashfiles) == len(taskhashlist):
foundall = True
break
else:
- try:
- filedates[fullpath] = os.stat(fullpath).st_mtime
- except OSError:
- continue
hashval = get_hashval(fullpath)
- hashfiles[hashval] = fullpath
+ hashfiles[hashval] = {'path':fullpath, 'sstate':False, 'time':get_time(fullpath)}
- if not taskhashlist or (len(filedates) < 2 and not foundall):
+ if not taskhashlist or (len(hashfiles) < 2 and not foundall):
# That didn't work, look in sstate-cache
hashes = taskhashlist or ['?' * 64]
localdata = bb.data.createCopy(d)
@@ -412,22 +414,15 @@ def find_siginfo(pn, taskname, taskhashlist, d):
localdata.setVar('SSTATE_EXTRAPATH', "${NATIVELSBSTRING}/")
filespec = '%s.siginfo' % localdata.getVar('SSTATE_PKG')
+ bb.debug(1, "Calling glob.glob on {}".format(filespec))
matchedfiles = glob.glob(filespec)
for fullpath in matchedfiles:
actual_hashval = get_hashval(fullpath)
if actual_hashval in hashfiles:
continue
- hashfiles[hashval] = fullpath
- if not taskhashlist:
- try:
- filedates[fullpath] = os.stat(fullpath).st_mtime
- except:
- continue
+ hashfiles[actual_hashval] = {'path':fullpath, 'sstate':True, 'time':get_time(fullpath)}
- if taskhashlist:
- return hashfiles
- else:
- return filedates
+ return hashfiles
bb.siggen.find_siginfo = find_siginfo
diff --git a/meta/lib/oeqa/selftest/cases/sstatetests.py b/meta/lib/oeqa/selftest/cases/sstatetests.py
index f5b3437d86b..83abcdfdd62 100644
--- a/meta/lib/oeqa/selftest/cases/sstatetests.py
+++ b/meta/lib/oeqa/selftest/cases/sstatetests.py
@@ -765,14 +765,14 @@ addtask tmptask2 before do_tmptask1
hashes = [hash1, hash2]
hashfiles = find_siginfo(key, None, hashes)
self.assertCountEqual(hashes, hashfiles)
- bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb)
+ bb.siggen.compare_sigfiles(hashfiles[hash1]['path'], hashfiles[hash2]['path'], recursecb)
for pn in pns:
recursecb_count = 0
- filedates = find_siginfo(pn, "do_tmptask1")
- self.assertGreaterEqual(len(filedates), 2)
- latestfiles = sorted(filedates.keys(), key=lambda f: filedates[f])[-2:]
- bb.siggen.compare_sigfiles(latestfiles[-2], latestfiles[-1], recursecb)
+ matches = find_siginfo(pn, "do_tmptask1")
+ self.assertGreaterEqual(len(matches), 2)
+ latesthashes = sorted(matches.keys(), key=lambda h: matches[h]['time'])[-2:]
+ bb.siggen.compare_sigfiles(matches[latesthashes[-2]]['path'], matches[latesthashes[-1]]['path'], recursecb)
self.assertEqual(recursecb_count,1)
class SStatePrintdiff(SStateBase):
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 7/9] bitbake-diffsigs/runqueue: adapt to reworked find_siginfo()
2023-12-14 13:45 [PATCH 1/9] oeqa/selftest/sstatetests: re-work CDN tests, add local cache tests Alexander Kanavin
` (4 preceding siblings ...)
2023-12-14 13:45 ` [PATCH 6/9] sstatesig/find_siginfo: unify a disjointed API Alexander Kanavin
@ 2023-12-14 13:45 ` Alexander Kanavin
2023-12-14 13:45 ` [PATCH 8/9] bitbake/runqueue: prioritize local stamps over sstate signatures in printdiff Alexander Kanavin
2023-12-14 13:45 ` [PATCH 9/9] bitbake/runqueue: add debugging for find_siginfo() calls Alexander Kanavin
7 siblings, 0 replies; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-14 13:45 UTC (permalink / raw)
To: openembedded-core; +Cc: Alexander Kanavin
In particular having 'time' explicitly used as a sorting key should make it
more clear how the entries are being sorted.
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
bitbake/bin/bitbake-diffsigs | 11 +++++++----
bitbake/lib/bb/runqueue.py | 10 +++++-----
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/bitbake/bin/bitbake-diffsigs b/bitbake/bin/bitbake-diffsigs
index fe0f33eea17..a8f49191b0c 100755
--- a/bitbake/bin/bitbake-diffsigs
+++ b/bitbake/bin/bitbake-diffsigs
@@ -72,13 +72,16 @@ def find_siginfo_task(bbhandler, pn, taskname, sig1=None, sig2=None):
elif sig2 not in sigfiles:
logger.error('No sigdata files found matching %s %s with signature %s' % (pn, taskname, sig2))
sys.exit(1)
- latestfiles = [sigfiles[sig1], sigfiles[sig2]]
else:
- filedates = find_siginfo(bbhandler, pn, taskname)
- latestfiles = sorted(filedates.keys(), key=lambda f: filedates[f])[-2:]
- if not latestfiles:
+ sigfiles = find_siginfo(bbhandler, pn, taskname)
+ latestsigs = sorted(sigfiles.keys(), key=lambda h: sigfiles[h]['time'])[-2:]
+ if not latestsigs:
logger.error('No sigdata files found matching %s %s' % (pn, taskname))
sys.exit(1)
+ sig1 = latestsigs[0]
+ sig2 = latestsigs[1]
+
+ latestfiles = [sigfiles[sig1]['path'], sigfiles[sig2]['path']]
return latestfiles
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 61effe24fae..ac5222514de 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -1755,7 +1755,7 @@ class RunQueue:
recout = []
if len(hashfiles) == 2:
- out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb)
+ out2 = bb.siggen.compare_sigfiles(hashfiles[hash1]['path'], hashfiles[hash2]['path'], recursecb)
recout.extend(list(' ' + l for l in out2))
else:
recout.append("Unable to find matching sigdata for %s with hashes %s or %s" % (key, hash1, hash2))
@@ -1769,14 +1769,14 @@ class RunQueue:
h = self.rqdata.runtaskentries[tid].unihash
matches = bb.siggen.find_siginfo(pn, taskname, [], self.cooker.databuilder.mcdata[mc])
match = None
- for m in matches:
- if h in m:
- match = m
+ for m in matches.values():
+ if h in m['path']:
+ match = m['path']
if match is None:
bb.fatal("Can't find a task we're supposed to have written out? (hash: %s tid: %s)?" % (h, tid))
matches = {k : v for k, v in iter(matches.items()) if h not in k}
if matches:
- latestmatch = sorted(matches.keys(), key=lambda f: matches[f])[-1]
+ latestmatch = matches[sorted(matches.keys(), key=lambda h: matches[h]['time'])[-1]]['path']
prevh = __find_sha256__.search(latestmatch).group(0)
output = bb.siggen.compare_sigfiles(latestmatch, match, recursecb)
bb.plain("\nTask %s:%s couldn't be used from the cache because:\n We need hash %s, most recent matching task was %s\n " % (pn, taskname, h, prevh) + '\n '.join(output))
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 8/9] bitbake/runqueue: prioritize local stamps over sstate signatures in printdiff
2023-12-14 13:45 [PATCH 1/9] oeqa/selftest/sstatetests: re-work CDN tests, add local cache tests Alexander Kanavin
` (5 preceding siblings ...)
2023-12-14 13:45 ` [PATCH 7/9] bitbake-diffsigs/runqueue: adapt to reworked find_siginfo() Alexander Kanavin
@ 2023-12-14 13:45 ` Alexander Kanavin
2023-12-14 13:45 ` [PATCH 9/9] bitbake/runqueue: add debugging for find_siginfo() calls Alexander Kanavin
7 siblings, 0 replies; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-14 13:45 UTC (permalink / raw)
To: openembedded-core; +Cc: Alexander Kanavin
Even with the reworked printdiff code, sstate which is heavily used in parallel
can throw races at the tests: if a new matching, but otherwise unrelated
sstate signature appears between writing out local stamps and listing
matching sstate files, then that signature will be deemed 'the latest'
and the actual local stamp will be discarded. This change ensures
the scenario does not happen.
It also makes use of the reworked find_siginfo(), particularly the 'sstate'
entry in returned results.
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
bitbake/lib/bb/runqueue.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index ac5222514de..2d2b28b3c99 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -1775,6 +1775,9 @@ class RunQueue:
if match is None:
bb.fatal("Can't find a task we're supposed to have written out? (hash: %s tid: %s)?" % (h, tid))
matches = {k : v for k, v in iter(matches.items()) if h not in k}
+ matches_local = {k : v for k, v in iter(matches.items()) if h not in k and not v['sstate']}
+ if matches_local:
+ matches = matches_local
if matches:
latestmatch = matches[sorted(matches.keys(), key=lambda h: matches[h]['time'])[-1]]['path']
prevh = __find_sha256__.search(latestmatch).group(0)
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 9/9] bitbake/runqueue: add debugging for find_siginfo() calls
2023-12-14 13:45 [PATCH 1/9] oeqa/selftest/sstatetests: re-work CDN tests, add local cache tests Alexander Kanavin
` (6 preceding siblings ...)
2023-12-14 13:45 ` [PATCH 8/9] bitbake/runqueue: prioritize local stamps over sstate signatures in printdiff Alexander Kanavin
@ 2023-12-14 13:45 ` Alexander Kanavin
7 siblings, 0 replies; 14+ messages in thread
From: Alexander Kanavin @ 2023-12-14 13:45 UTC (permalink / raw)
To: openembedded-core; +Cc: Alexander Kanavin
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
bitbake/lib/bb/runqueue.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 2d2b28b3c99..bb75e81c557 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -1751,7 +1751,9 @@ class RunQueue:
# Define recursion callback
def recursecb(key, hash1, hash2):
hashes = [hash1, hash2]
+ bb.debug(1, "Recursively looking for recipe {} hashes {}".format(key, hashes))
hashfiles = bb.siggen.find_siginfo(key, None, hashes, self.cfgData)
+ bb.debug(1, "Found hashfiles:\n{}".format(hashfiles))
recout = []
if len(hashfiles) == 2:
@@ -1767,7 +1769,9 @@ class RunQueue:
(mc, fn, taskname, taskfn) = split_tid_mcfn(tid)
pn = self.rqdata.dataCaches[mc].pkg_fn[taskfn]
h = self.rqdata.runtaskentries[tid].unihash
+ bb.debug(1, "Looking for recipe {} task {}".format(pn, taskname))
matches = bb.siggen.find_siginfo(pn, taskname, [], self.cooker.databuilder.mcdata[mc])
+ bb.debug(1, "Found hashfiles:\n{}".format(matches))
match = None
for m in matches.values():
if h in m['path']:
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread