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>
This commit is contained in:
Richard Purdie 2016-04-02 17:11:26 +01:00
parent 3e1b5e0685
commit 80336270f3
1 changed files with 49 additions and 11 deletions

View File

@ -248,6 +248,7 @@ class SignatureGeneratorBasic(SignatureGenerator):
bb.utils.mkdirhier(os.path.dirname(sigfile))
data = {}
data['task'] = task
data['basewhitelist'] = self.basewhitelist
data['taskwhitelist'] = self.taskwhitelist
data['taskdeps'] = self.taskdeps[fn][task]
@ -267,6 +268,7 @@ class SignatureGeneratorBasic(SignatureGenerator):
data['runtaskhashes'] = {}
for dep in data['runtaskdeps']:
data['runtaskhashes'][dep] = self.taskhash[dep]
data['taskhash'] = self.taskhash[k]
taint = self.read_taint(fn, task, stampbase)
if taint:
@ -290,6 +292,15 @@ class SignatureGeneratorBasic(SignatureGenerator):
pass
raise err
computed_basehash = calc_basehash(data)
if computed_basehash != self.basehash[k]:
bb.error("Basehash mismatch %s verses %s for %s" % (computed_basehash, self.basehash[k], k))
if k in self.taskhash:
computed_taskhash = calc_taskhash(data)
if computed_taskhash != self.taskhash[k]:
bb.error("Taskhash mismatch %s verses %s for %s" % (computed_taskhash, self.taskhash[k], k))
def dump_sigs(self, dataCache, options):
for fn in self.taskdeps:
for task in self.taskdeps[fn]:
@ -506,6 +517,37 @@ def compare_sigfiles(a, b, recursecb = None):
return output
def calc_basehash(sigdata):
task = sigdata['task']
basedata = sigdata['varvals'][task]
if basedata is None:
basedata = ''
alldeps = sigdata['taskdeps']
for dep in alldeps:
basedata = basedata + dep
val = sigdata['varvals'][dep]
if val is not None:
basedata = basedata + str(val)
return hashlib.md5(basedata).hexdigest()
def calc_taskhash(sigdata):
data = sigdata['basehash']
for dep in sigdata['runtaskdeps']:
data = data + sigdata['runtaskhashes'][dep]
for c in sigdata['file_checksum_values']:
data = data + c[1]
if 'taint' in sigdata:
data = data + sigdata['taint']
return hashlib.md5(data).hexdigest()
def dump_sigfile(a):
output = []
@ -539,17 +581,13 @@ def dump_sigfile(a):
if 'taint' in a_data:
output.append("Tainted (by forced/invalidated task): %s" % a_data['taint'])
data = a_data['basehash']
for dep in a_data['runtaskdeps']:
data = data + a_data['runtaskhashes'][dep]
if 'task' in a_data:
computed_basehash = calc_basehash(a_data)
output.append("Computed base hash is %s and from file %s" % (computed_basehash, a_data['basehash']))
else:
output.append("Unable to compute base hash")
for c in a_data['file_checksum_values']:
data = data + c[1]
if 'taint' in a_data:
data = data + a_data['taint']
h = hashlib.md5(data).hexdigest()
output.append("Computed Hash is %s" % h)
computed_taskhash = calc_taskhash(a_data)
output.append("Computed task hash is %s" % computed_taskhash)
return output