diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-04-02 17:11:26 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-04-03 22:50:17 +0100 |
commit | 80336270f3ccecd8504590714428db68dd68f651 (patch) | |
tree | 9eb3b09d1cbabd94c4a7c6126b4bb072f506a1bd | |
parent | 3e1b5e0685eba0f56ad82f49e28cf8a173affad8 (diff) | |
download | poky-80336270f3ccecd8504590714428db68dd68f651.tar.gz |
bitbake: siggen: Add checksum recalculation/checking code
In theory all the information to recalcuate the task signatures was written
into the siginfo/sigdata files. In reality, some of the information was
written into the filename.
Firstly this patch duplicates that info into the file itself just for easy
of use since its small.
Secondly, we abstract out the existing "calculate the checksum" code for
the taskhash, and add a function to calculate the bashhash based on the
informaiton within the file.
Finally, we call these functions when we're writing out the data to check
that the data we're writing is consistent. I've found a couple of places
it wasn't and its good to know about these in advance, rather than having
a siginfo/sigdata file which a given hash in its filename but a contents
which give a different result.
This should all combine to avoid a certain class of checksum bugs making
it into world, and identifying problems in advance.
(Bitbake rev: 0f50a18d7a0ea0d68edd8e5217e29111f4b1ea0b)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | bitbake/lib/bb/siggen.py | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/bitbake/lib/bb/siggen.py b/bitbake/lib/bb/siggen.py index d8ba1d47a3..2f0fb71c78 100644 --- a/bitbake/lib/bb/siggen.py +++ b/bitbake/lib/bb/siggen.py | |||
@@ -248,6 +248,7 @@ class SignatureGeneratorBasic(SignatureGenerator): | |||
248 | bb.utils.mkdirhier(os.path.dirname(sigfile)) | 248 | bb.utils.mkdirhier(os.path.dirname(sigfile)) |
249 | 249 | ||
250 | data = {} | 250 | data = {} |
251 | data['task'] = task | ||
251 | data['basewhitelist'] = self.basewhitelist | 252 | data['basewhitelist'] = self.basewhitelist |
252 | data['taskwhitelist'] = self.taskwhitelist | 253 | data['taskwhitelist'] = self.taskwhitelist |
253 | data['taskdeps'] = self.taskdeps[fn][task] | 254 | data['taskdeps'] = self.taskdeps[fn][task] |
@@ -267,6 +268,7 @@ class SignatureGeneratorBasic(SignatureGenerator): | |||
267 | data['runtaskhashes'] = {} | 268 | data['runtaskhashes'] = {} |
268 | for dep in data['runtaskdeps']: | 269 | for dep in data['runtaskdeps']: |
269 | data['runtaskhashes'][dep] = self.taskhash[dep] | 270 | data['runtaskhashes'][dep] = self.taskhash[dep] |
271 | data['taskhash'] = self.taskhash[k] | ||
270 | 272 | ||
271 | taint = self.read_taint(fn, task, stampbase) | 273 | taint = self.read_taint(fn, task, stampbase) |
272 | if taint: | 274 | if taint: |
@@ -290,6 +292,15 @@ class SignatureGeneratorBasic(SignatureGenerator): | |||
290 | pass | 292 | pass |
291 | raise err | 293 | raise err |
292 | 294 | ||
295 | computed_basehash = calc_basehash(data) | ||
296 | if computed_basehash != self.basehash[k]: | ||
297 | bb.error("Basehash mismatch %s verses %s for %s" % (computed_basehash, self.basehash[k], k)) | ||
298 | if k in self.taskhash: | ||
299 | computed_taskhash = calc_taskhash(data) | ||
300 | if computed_taskhash != self.taskhash[k]: | ||
301 | bb.error("Taskhash mismatch %s verses %s for %s" % (computed_taskhash, self.taskhash[k], k)) | ||
302 | |||
303 | |||
293 | def dump_sigs(self, dataCache, options): | 304 | def dump_sigs(self, dataCache, options): |
294 | for fn in self.taskdeps: | 305 | for fn in self.taskdeps: |
295 | for task in self.taskdeps[fn]: | 306 | for task in self.taskdeps[fn]: |
@@ -506,6 +517,37 @@ def compare_sigfiles(a, b, recursecb = None): | |||
506 | return output | 517 | return output |
507 | 518 | ||
508 | 519 | ||
520 | def calc_basehash(sigdata): | ||
521 | task = sigdata['task'] | ||
522 | basedata = sigdata['varvals'][task] | ||
523 | |||
524 | if basedata is None: | ||
525 | basedata = '' | ||
526 | |||
527 | alldeps = sigdata['taskdeps'] | ||
528 | for dep in alldeps: | ||
529 | basedata = basedata + dep | ||
530 | val = sigdata['varvals'][dep] | ||
531 | if val is not None: | ||
532 | basedata = basedata + str(val) | ||
533 | |||
534 | return hashlib.md5(basedata).hexdigest() | ||
535 | |||
536 | def calc_taskhash(sigdata): | ||
537 | data = sigdata['basehash'] | ||
538 | |||
539 | for dep in sigdata['runtaskdeps']: | ||
540 | data = data + sigdata['runtaskhashes'][dep] | ||
541 | |||
542 | for c in sigdata['file_checksum_values']: | ||
543 | data = data + c[1] | ||
544 | |||
545 | if 'taint' in sigdata: | ||
546 | data = data + sigdata['taint'] | ||
547 | |||
548 | return hashlib.md5(data).hexdigest() | ||
549 | |||
550 | |||
509 | def dump_sigfile(a): | 551 | def dump_sigfile(a): |
510 | output = [] | 552 | output = [] |
511 | 553 | ||
@@ -539,17 +581,13 @@ def dump_sigfile(a): | |||
539 | if 'taint' in a_data: | 581 | if 'taint' in a_data: |
540 | output.append("Tainted (by forced/invalidated task): %s" % a_data['taint']) | 582 | output.append("Tainted (by forced/invalidated task): %s" % a_data['taint']) |
541 | 583 | ||
542 | data = a_data['basehash'] | 584 | if 'task' in a_data: |
543 | for dep in a_data['runtaskdeps']: | 585 | computed_basehash = calc_basehash(a_data) |
544 | data = data + a_data['runtaskhashes'][dep] | 586 | output.append("Computed base hash is %s and from file %s" % (computed_basehash, a_data['basehash'])) |
545 | 587 | else: | |
546 | for c in a_data['file_checksum_values']: | 588 | output.append("Unable to compute base hash") |
547 | data = data + c[1] | ||
548 | |||
549 | if 'taint' in a_data: | ||
550 | data = data + a_data['taint'] | ||
551 | 589 | ||
552 | h = hashlib.md5(data).hexdigest() | 590 | computed_taskhash = calc_taskhash(a_data) |
553 | output.append("Computed Hash is %s" % h) | 591 | output.append("Computed task hash is %s" % computed_taskhash) |
554 | 592 | ||
555 | return output | 593 | return output |