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 10*00e122a7SBrad 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 19*00e122a7SBrad Bishop# extract the hash from past the last colon to last underscore 20*00e122a7SBrad Bishopdef extract_sha(filename): 21*00e122a7SBrad Bishop return filename.split(':')[7].split('_')[0] 22*00e122a7SBrad Bishop 23*00e122a7SBrad Bishop# get all files in a directory, extract hash and make 24*00e122a7SBrad Bishop# a map from hash to list of file with that hash 25*00e122a7SBrad Bishopdef map_sha_to_files(dir_, prefix, sha_map): 26*00e122a7SBrad Bishop sstate_prefix_path = dir_ + '/' + prefix + '/' 27*00e122a7SBrad Bishop sstate_files = os.listdir(sstate_prefix_path) 28*00e122a7SBrad Bishop for f in sstate_files: 29*00e122a7SBrad Bishop try: 30*00e122a7SBrad Bishop sha = extract_sha(f) 31*00e122a7SBrad Bishop if sha not in sha_map: 32*00e122a7SBrad Bishop sha_map[sha] = [] 33*00e122a7SBrad Bishop sha_map[sha].append(sstate_prefix_path + f) 34*00e122a7SBrad Bishop except IndexError: 35*00e122a7SBrad Bishop continue 36*00e122a7SBrad Bishop 37*00e122a7SBrad Bishop# given a prefix build a map of hash to list of files 38*00e122a7SBrad Bishopdef build_sha_cache(prefix): 39*00e122a7SBrad Bishop sha_map = {} 40*00e122a7SBrad Bishop 41*00e122a7SBrad Bishop sstate_dir = sys.argv[2] 42*00e122a7SBrad Bishop map_sha_to_files(sstate_dir, prefix, sha_map) 43*00e122a7SBrad Bishop 44*00e122a7SBrad Bishop native_sstate_dir = sys.argv[2] + '/' + sys.argv[4] 45*00e122a7SBrad Bishop map_sha_to_files(native_sstate_dir, prefix, sha_map) 46*00e122a7SBrad Bishop 47*00e122a7SBrad Bishop return sha_map 48*00e122a7SBrad Bishop 49eb8dc403SDave Cobbleyif len(sys.argv) < 5: 50eb8dc403SDave Cobbley print("Incorrect number of arguments specified") 51eb8dc403SDave Cobbley print("syntax: gen-lockedsig-cache <locked-sigs.inc> <input-cachedir> <output-cachedir> <nativelsbstring> [filterfile]") 52eb8dc403SDave Cobbley sys.exit(1) 53eb8dc403SDave Cobbley 54eb8dc403SDave Cobbleyfilterlist = [] 55eb8dc403SDave Cobbleyif len(sys.argv) > 5: 56eb8dc403SDave Cobbley print('Reading filter file %s' % sys.argv[5]) 57eb8dc403SDave Cobbley with open(sys.argv[5]) as f: 58eb8dc403SDave Cobbley for l in f.readlines(): 59eb8dc403SDave Cobbley if ":" in l: 60eb8dc403SDave Cobbley filterlist.append(l.rstrip()) 61eb8dc403SDave Cobbley 62eb8dc403SDave Cobbleyprint('Reading %s' % sys.argv[1]) 63eb8dc403SDave Cobbleysigs = [] 64eb8dc403SDave Cobbleywith open(sys.argv[1]) as f: 65eb8dc403SDave Cobbley for l in f.readlines(): 66eb8dc403SDave Cobbley if ":" in l: 67eb8dc403SDave Cobbley task, sig = l.split()[0].rsplit(':', 1) 68eb8dc403SDave Cobbley if filterlist and not task in filterlist: 69eb8dc403SDave Cobbley print('Filtering out %s' % task) 70eb8dc403SDave Cobbley else: 71eb8dc403SDave Cobbley sigs.append(sig) 72eb8dc403SDave Cobbley 73eb8dc403SDave Cobbleyprint('Gathering file list') 74*00e122a7SBrad Bishopstart_time = time.perf_counter() 75eb8dc403SDave Cobbleyfiles = set() 76*00e122a7SBrad Bishopsstate_content_cache = {} 77eb8dc403SDave Cobbleyfor s in sigs: 78*00e122a7SBrad Bishop prefix = s[:2] 79*00e122a7SBrad Bishop if prefix not in sstate_content_cache: 80*00e122a7SBrad Bishop sstate_content_cache[prefix] = build_sha_cache(prefix) 81*00e122a7SBrad Bishop 82*00e122a7SBrad Bishop for f in sstate_content_cache[prefix][s]: 83*00e122a7SBrad Bishop files.add(f) 84*00e122a7SBrad Bishop 85*00e122a7SBrad Bishopelapsed = time.perf_counter() - start_time 86*00e122a7SBrad Bishopprint("Gathering file list took %.1fs" % elapsed) 87eb8dc403SDave Cobbley 88eb8dc403SDave Cobbleyprint('Processing files') 89eb8dc403SDave Cobbleyfor f in files: 90eb8dc403SDave Cobbley sys.stdout.write('Processing %s... ' % f) 91eb8dc403SDave Cobbley _, ext = os.path.splitext(f) 92eb8dc403SDave Cobbley if not ext in ['.tgz', '.siginfo', '.sig']: 93eb8dc403SDave Cobbley # Most likely a temp file, skip it 94eb8dc403SDave Cobbley print('skipping') 95eb8dc403SDave Cobbley continue 96eb8dc403SDave Cobbley dst = os.path.join(sys.argv[3], os.path.relpath(f, sys.argv[2])) 97eb8dc403SDave Cobbley destdir = os.path.dirname(dst) 98eb8dc403SDave Cobbley mkdir(destdir) 99eb8dc403SDave Cobbley 100eb8dc403SDave Cobbley src = os.path.realpath(f) 101eb8dc403SDave Cobbley if os.path.exists(dst): 102eb8dc403SDave Cobbley os.remove(dst) 103eb8dc403SDave Cobbley if (os.stat(src).st_dev == os.stat(destdir).st_dev): 104eb8dc403SDave Cobbley print('linking') 105eb8dc403SDave Cobbley try: 106eb8dc403SDave Cobbley os.link(src, dst) 107eb8dc403SDave Cobbley except OSError as e: 108eb8dc403SDave Cobbley print('hard linking failed, copying') 109eb8dc403SDave Cobbley shutil.copyfile(src, dst) 110eb8dc403SDave Cobbley else: 111eb8dc403SDave Cobbley print('copying') 112eb8dc403SDave Cobbley shutil.copyfile(src, dst) 113eb8dc403SDave Cobbley 114eb8dc403SDave Cobbleyprint('Done!') 115