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