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