xref: /openbmc/openbmc/poky/scripts/gen-lockedsig-cache (revision 92b42cb35d755f8cfe6c17d403711a536e0f0721)
1eb8dc403SDave Cobbley#!/usr/bin/env python3
2c342db35SBrad Bishop#
3*92b42cb3SPatrick Williams#
4*92b42cb3SPatrick Williams# Copyright OpenEmbedded Contributors
5*92b42cb3SPatrick Williams#
6c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only
7c342db35SBrad Bishop#
8eb8dc403SDave Cobbley
9eb8dc403SDave Cobbleyimport os
10eb8dc403SDave Cobbleyimport sys
11eb8dc403SDave Cobbleyimport shutil
12eb8dc403SDave Cobbleyimport errno
1300e122a7SBrad Bishopimport time
14eb8dc403SDave Cobbley
15eb8dc403SDave Cobbleydef mkdir(d):
16eb8dc403SDave Cobbley    try:
17eb8dc403SDave Cobbley        os.makedirs(d)
18eb8dc403SDave Cobbley    except OSError as e:
19eb8dc403SDave Cobbley        if e.errno != errno.EEXIST:
20eb8dc403SDave Cobbley            raise e
21eb8dc403SDave Cobbley
2200e122a7SBrad Bishop# extract the hash from past the last colon to last underscore
2300e122a7SBrad Bishopdef extract_sha(filename):
2400e122a7SBrad Bishop    return filename.split(':')[7].split('_')[0]
2500e122a7SBrad Bishop
2600e122a7SBrad Bishop# get all files in a directory, extract hash and make
2700e122a7SBrad Bishop# a map from hash to list of file with that hash
2800e122a7SBrad Bishopdef map_sha_to_files(dir_, prefix, sha_map):
2900e122a7SBrad Bishop    sstate_prefix_path = dir_ + '/' + prefix + '/'
30f3f93bb8SBrad Bishop    if not os.path.exists(sstate_prefix_path):
31f3f93bb8SBrad Bishop        return
3200e122a7SBrad Bishop    sstate_files = os.listdir(sstate_prefix_path)
3300e122a7SBrad Bishop    for f in sstate_files:
3400e122a7SBrad Bishop        try:
3500e122a7SBrad Bishop            sha = extract_sha(f)
3600e122a7SBrad Bishop            if sha not in sha_map:
3700e122a7SBrad Bishop                sha_map[sha] = []
3800e122a7SBrad Bishop            sha_map[sha].append(sstate_prefix_path + f)
3900e122a7SBrad Bishop        except IndexError:
4000e122a7SBrad Bishop            continue
4100e122a7SBrad Bishop
4200e122a7SBrad Bishop# given a prefix build a map of hash to list of files
4300e122a7SBrad Bishopdef build_sha_cache(prefix):
4400e122a7SBrad Bishop    sha_map = {}
4500e122a7SBrad Bishop
4600e122a7SBrad Bishop    sstate_dir = sys.argv[2]
4700e122a7SBrad Bishop    map_sha_to_files(sstate_dir, prefix, sha_map)
4800e122a7SBrad Bishop
4900e122a7SBrad Bishop    native_sstate_dir = sys.argv[2] + '/' + sys.argv[4]
5000e122a7SBrad Bishop    map_sha_to_files(native_sstate_dir, prefix, sha_map)
5100e122a7SBrad Bishop
5200e122a7SBrad Bishop    return sha_map
5300e122a7SBrad Bishop
54eb8dc403SDave Cobbleyif len(sys.argv) < 5:
55eb8dc403SDave Cobbley    print("Incorrect number of arguments specified")
56eb8dc403SDave Cobbley    print("syntax: gen-lockedsig-cache <locked-sigs.inc> <input-cachedir> <output-cachedir> <nativelsbstring> [filterfile]")
57eb8dc403SDave Cobbley    sys.exit(1)
58eb8dc403SDave Cobbley
59eb8dc403SDave Cobbleyfilterlist = []
60eb8dc403SDave Cobbleyif len(sys.argv) > 5:
61eb8dc403SDave Cobbley    print('Reading filter file %s' % sys.argv[5])
62eb8dc403SDave Cobbley    with open(sys.argv[5]) as f:
63eb8dc403SDave Cobbley        for l in f.readlines():
64eb8dc403SDave Cobbley            if ":" in l:
65eb8dc403SDave Cobbley                filterlist.append(l.rstrip())
66eb8dc403SDave Cobbley
67eb8dc403SDave Cobbleyprint('Reading %s' % sys.argv[1])
68eb8dc403SDave Cobbleysigs = []
69eb8dc403SDave Cobbleywith open(sys.argv[1]) as f:
70eb8dc403SDave Cobbley    for l in f.readlines():
71eb8dc403SDave Cobbley        if ":" in l:
72eb8dc403SDave Cobbley            task, sig = l.split()[0].rsplit(':', 1)
73eb8dc403SDave Cobbley            if filterlist and not task in filterlist:
74eb8dc403SDave Cobbley                print('Filtering out %s' % task)
75eb8dc403SDave Cobbley            else:
76eb8dc403SDave Cobbley                sigs.append(sig)
77eb8dc403SDave Cobbley
78eb8dc403SDave Cobbleyprint('Gathering file list')
7900e122a7SBrad Bishopstart_time = time.perf_counter()
80eb8dc403SDave Cobbleyfiles = set()
8100e122a7SBrad Bishopsstate_content_cache = {}
82eb8dc403SDave Cobbleyfor s in sigs:
8300e122a7SBrad Bishop    prefix = s[:2]
8482c905dcSAndrew Geissler    prefix2 = s[2:4]
8500e122a7SBrad Bishop    if prefix not in sstate_content_cache:
8682c905dcSAndrew Geissler        sstate_content_cache[prefix] = {}
8782c905dcSAndrew Geissler    if prefix2 not in sstate_content_cache[prefix]:
8882c905dcSAndrew Geissler        sstate_content_cache[prefix][prefix2] = build_sha_cache(prefix + "/" + prefix2)
8900e122a7SBrad Bishop
9082c905dcSAndrew Geissler    if s in sstate_content_cache[prefix][prefix2]:
9182c905dcSAndrew Geissler        for f in sstate_content_cache[prefix][prefix2][s]:
9200e122a7SBrad Bishop            files.add(f)
9300e122a7SBrad Bishop
9400e122a7SBrad Bishopelapsed = time.perf_counter() - start_time
9500e122a7SBrad Bishopprint("Gathering file list took %.1fs" % elapsed)
96eb8dc403SDave Cobbley
97eb8dc403SDave Cobbleyprint('Processing files')
98eb8dc403SDave Cobbleyfor f in files:
99eb8dc403SDave Cobbley    sys.stdout.write('Processing %s... ' % f)
100eff27476SAndrew Geissler    if not f.endswith(('.tar.zst', '.siginfo', '.sig')):
101eb8dc403SDave Cobbley        # Most likely a temp file, skip it
102eb8dc403SDave Cobbley        print('skipping')
103eb8dc403SDave Cobbley        continue
104eb8dc403SDave Cobbley    dst = os.path.join(sys.argv[3], os.path.relpath(f, sys.argv[2]))
105eb8dc403SDave Cobbley    destdir = os.path.dirname(dst)
106eb8dc403SDave Cobbley    mkdir(destdir)
107eb8dc403SDave Cobbley
108eb8dc403SDave Cobbley    src = os.path.realpath(f)
109eb8dc403SDave Cobbley    if os.path.exists(dst):
110eb8dc403SDave Cobbley        os.remove(dst)
111eb8dc403SDave Cobbley    if (os.stat(src).st_dev == os.stat(destdir).st_dev):
112eb8dc403SDave Cobbley        print('linking')
113eb8dc403SDave Cobbley        try:
114eb8dc403SDave Cobbley            os.link(src, dst)
115eb8dc403SDave Cobbley        except OSError as e:
116eb8dc403SDave Cobbley            print('hard linking failed, copying')
117eb8dc403SDave Cobbley            shutil.copyfile(src, dst)
118eb8dc403SDave Cobbley    else:
119eb8dc403SDave Cobbley        print('copying')
120eb8dc403SDave Cobbley        shutil.copyfile(src, dst)
121eb8dc403SDave Cobbley
122eb8dc403SDave Cobbleyprint('Done!')
123