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