summaryrefslogtreecommitdiffstats
path: root/meta/classes/sstate.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'meta/classes/sstate.bbclass')
-rw-r--r--meta/classes/sstate.bbclass98
1 files changed, 76 insertions, 22 deletions
diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index a8e169a10b..1058778980 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -20,7 +20,7 @@ def generate_sstatefn(spec, hash, taskname, siginfo, d):
20 components = spec.split(":") 20 components = spec.split(":")
21 # Fields 0,5,6 are mandatory, 1 is most useful, 2,3,4 are just for information 21 # Fields 0,5,6 are mandatory, 1 is most useful, 2,3,4 are just for information
22 # 7 is for the separators 22 # 7 is for the separators
23 avail = (254 - len(hash + "_" + taskname + extension) - len(components[0]) - len(components[1]) - len(components[5]) - len(components[6]) - 7) // 3 23 avail = (limit - len(hash + "_" + taskname + extension) - len(components[0]) - len(components[1]) - len(components[5]) - len(components[6]) - 7) // 3
24 components[2] = components[2][:avail] 24 components[2] = components[2][:avail]
25 components[3] = components[3][:avail] 25 components[3] = components[3][:avail]
26 components[4] = components[4][:avail] 26 components[4] = components[4][:avail]
@@ -123,8 +123,6 @@ SSTATE_HASHEQUIV_REPORT_TASKDATA[doc] = "Report additional useful data to the \
123python () { 123python () {
124 if bb.data.inherits_class('native', d): 124 if bb.data.inherits_class('native', d):
125 d.setVar('SSTATE_PKGARCH', d.getVar('BUILD_ARCH', False)) 125 d.setVar('SSTATE_PKGARCH', d.getVar('BUILD_ARCH', False))
126 if d.getVar("PN") == "pseudo-native":
127 d.appendVar('SSTATE_PKGARCH', '_${ORIGNATIVELSBSTRING}')
128 elif bb.data.inherits_class('crosssdk', d): 126 elif bb.data.inherits_class('crosssdk', d):
129 d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS}")) 127 d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS}"))
130 elif bb.data.inherits_class('cross', d): 128 elif bb.data.inherits_class('cross', d):
@@ -319,6 +317,8 @@ def sstate_install(ss, d):
319 if os.path.exists(i): 317 if os.path.exists(i):
320 with open(i, "r") as f: 318 with open(i, "r") as f:
321 manifests = f.readlines() 319 manifests = f.readlines()
320 # We append new entries, we don't remove older entries which may have the same
321 # manifest name but different versions from stamp/workdir. See below.
322 if filedata not in manifests: 322 if filedata not in manifests:
323 with open(i, "a+") as f: 323 with open(i, "a+") as f:
324 f.write(filedata) 324 f.write(filedata)
@@ -481,7 +481,7 @@ def sstate_clean_cachefiles(d):
481 ss = sstate_state_fromvars(ld, task) 481 ss = sstate_state_fromvars(ld, task)
482 sstate_clean_cachefile(ss, ld) 482 sstate_clean_cachefile(ss, ld)
483 483
484def sstate_clean_manifest(manifest, d, prefix=None): 484def sstate_clean_manifest(manifest, d, canrace=False, prefix=None):
485 import oe.path 485 import oe.path
486 486
487 mfile = open(manifest) 487 mfile = open(manifest)
@@ -499,7 +499,9 @@ def sstate_clean_manifest(manifest, d, prefix=None):
499 if entry.endswith("/"): 499 if entry.endswith("/"):
500 if os.path.islink(entry[:-1]): 500 if os.path.islink(entry[:-1]):
501 os.remove(entry[:-1]) 501 os.remove(entry[:-1])
502 elif os.path.exists(entry) and len(os.listdir(entry)) == 0: 502 elif os.path.exists(entry) and len(os.listdir(entry)) == 0 and not canrace:
503 # Removing directories whilst builds are in progress exposes a race. Only
504 # do it in contexts where it is safe to do so.
503 os.rmdir(entry[:-1]) 505 os.rmdir(entry[:-1])
504 else: 506 else:
505 os.remove(entry) 507 os.remove(entry)
@@ -537,7 +539,7 @@ def sstate_clean(ss, d):
537 for lock in ss['lockfiles']: 539 for lock in ss['lockfiles']:
538 locks.append(bb.utils.lockfile(lock)) 540 locks.append(bb.utils.lockfile(lock))
539 541
540 sstate_clean_manifest(manifest, d) 542 sstate_clean_manifest(manifest, d, canrace=True)
541 543
542 for lock in locks: 544 for lock in locks:
543 bb.utils.unlockfile(lock) 545 bb.utils.unlockfile(lock)
@@ -638,10 +640,21 @@ python sstate_hardcode_path () {
638 640
639def sstate_package(ss, d): 641def sstate_package(ss, d):
640 import oe.path 642 import oe.path
643 import time
641 644
642 tmpdir = d.getVar('TMPDIR') 645 tmpdir = d.getVar('TMPDIR')
643 646
647 fixtime = False
648 if ss['task'] == "package":
649 fixtime = True
650
651 def fixtimestamp(root, path):
652 f = os.path.join(root, path)
653 if os.lstat(f).st_mtime > sde:
654 os.utime(f, (sde, sde), follow_symlinks=False)
655
644 sstatebuild = d.expand("${WORKDIR}/sstate-build-%s/" % ss['task']) 656 sstatebuild = d.expand("${WORKDIR}/sstate-build-%s/" % ss['task'])
657 sde = int(d.getVar("SOURCE_DATE_EPOCH") or time.time())
645 d.setVar("SSTATE_CURRTASK", ss['task']) 658 d.setVar("SSTATE_CURRTASK", ss['task'])
646 bb.utils.remove(sstatebuild, recurse=True) 659 bb.utils.remove(sstatebuild, recurse=True)
647 bb.utils.mkdirhier(sstatebuild) 660 bb.utils.mkdirhier(sstatebuild)
@@ -654,6 +667,8 @@ def sstate_package(ss, d):
654 # to sstate tasks but there aren't many of these so better just avoid them entirely. 667 # to sstate tasks but there aren't many of these so better just avoid them entirely.
655 for walkroot, dirs, files in os.walk(state[1]): 668 for walkroot, dirs, files in os.walk(state[1]):
656 for file in files + dirs: 669 for file in files + dirs:
670 if fixtime:
671 fixtimestamp(walkroot, file)
657 srcpath = os.path.join(walkroot, file) 672 srcpath = os.path.join(walkroot, file)
658 if not os.path.islink(srcpath): 673 if not os.path.islink(srcpath):
659 continue 674 continue
@@ -675,6 +690,11 @@ def sstate_package(ss, d):
675 bb.utils.mkdirhier(plain) 690 bb.utils.mkdirhier(plain)
676 bb.utils.mkdirhier(pdir) 691 bb.utils.mkdirhier(pdir)
677 os.rename(plain, pdir) 692 os.rename(plain, pdir)
693 if fixtime:
694 fixtimestamp(pdir, "")
695 for walkroot, dirs, files in os.walk(pdir):
696 for file in files + dirs:
697 fixtimestamp(walkroot, file)
678 698
679 d.setVar('SSTATE_BUILDDIR', sstatebuild) 699 d.setVar('SSTATE_BUILDDIR', sstatebuild)
680 d.setVar('SSTATE_INSTDIR', sstatebuild) 700 d.setVar('SSTATE_INSTDIR', sstatebuild)
@@ -701,9 +721,16 @@ def sstate_package(ss, d):
701 os.utime(siginfo, None) 721 os.utime(siginfo, None)
702 except PermissionError: 722 except PermissionError:
703 pass 723 pass
724 except OSError as e:
725 # Handle read-only file systems gracefully
726 import errno
727 if e.errno != errno.EROFS:
728 raise e
704 729
705 return 730 return
706 731
732sstate_package[vardepsexclude] += "SSTATE_SIG_KEY"
733
707def pstaging_fetch(sstatefetch, d): 734def pstaging_fetch(sstatefetch, d):
708 import bb.fetch2 735 import bb.fetch2
709 736
@@ -787,7 +814,7 @@ sstate_task_postfunc[dirs] = "${WORKDIR}"
787sstate_create_package () { 814sstate_create_package () {
788 # Exit early if it already exists 815 # Exit early if it already exists
789 if [ -e ${SSTATE_PKG} ]; then 816 if [ -e ${SSTATE_PKG} ]; then
790 [ ! -w ${SSTATE_PKG} ] || touch ${SSTATE_PKG} 817 touch ${SSTATE_PKG} 2>/dev/null || true
791 return 818 return
792 fi 819 fi
793 820
@@ -814,14 +841,18 @@ sstate_create_package () {
814 fi 841 fi
815 chmod 0664 $TFILE 842 chmod 0664 $TFILE
816 # Skip if it was already created by some other process 843 # Skip if it was already created by some other process
817 if [ ! -e ${SSTATE_PKG} ]; then 844 if [ -h ${SSTATE_PKG} ] && [ ! -e ${SSTATE_PKG} ]; then
845 # There is a symbolic link, but it links to nothing.
846 # Forcefully replace it with the new file.
847 ln -f $TFILE ${SSTATE_PKG} || true
848 elif [ ! -e ${SSTATE_PKG} ]; then
818 # Move into place using ln to attempt an atomic op. 849 # Move into place using ln to attempt an atomic op.
819 # Abort if it already exists 850 # Abort if it already exists
820 ln $TFILE ${SSTATE_PKG} && rm $TFILE 851 ln $TFILE ${SSTATE_PKG} || true
821 else 852 else
822 rm $TFILE 853 touch ${SSTATE_PKG} 2>/dev/null || true
823 fi 854 fi
824 [ ! -w ${SSTATE_PKG} ] || touch ${SSTATE_PKG} 855 rm $TFILE
825} 856}
826 857
827python sstate_sign_package () { 858python sstate_sign_package () {
@@ -850,12 +881,12 @@ python sstate_report_unihash() {
850# 881#
851sstate_unpack_package () { 882sstate_unpack_package () {
852 tar -xvzf ${SSTATE_PKG} 883 tar -xvzf ${SSTATE_PKG}
853 # update .siginfo atime on local/NFS mirror 884 # update .siginfo atime on local/NFS mirror if it is a symbolic link
854 [ -O ${SSTATE_PKG}.siginfo ] && [ -w ${SSTATE_PKG}.siginfo ] && [ -h ${SSTATE_PKG}.siginfo ] && touch -a ${SSTATE_PKG}.siginfo 885 [ ! -h ${SSTATE_PKG}.siginfo ] || [ ! -e ${SSTATE_PKG}.siginfo ] || touch -a ${SSTATE_PKG}.siginfo 2>/dev/null || true
855 # Use "! -w ||" to return true for read only files 886 # update each symbolic link instead of any referenced file
856 [ ! -w ${SSTATE_PKG} ] || touch --no-dereference ${SSTATE_PKG} 887 touch --no-dereference ${SSTATE_PKG} 2>/dev/null || true
857 [ ! -w ${SSTATE_PKG}.sig ] || [ ! -e ${SSTATE_PKG}.sig ] || touch --no-dereference ${SSTATE_PKG}.sig 888 [ ! -e ${SSTATE_PKG}.sig ] || touch --no-dereference ${SSTATE_PKG}.sig 2>/dev/null || true
858 [ ! -w ${SSTATE_PKG}.siginfo ] || [ ! -e ${SSTATE_PKG}.siginfo ] || touch --no-dereference ${SSTATE_PKG}.siginfo 889 [ ! -e ${SSTATE_PKG}.siginfo ] || touch --no-dereference ${SSTATE_PKG}.siginfo 2>/dev/null || true
859} 890}
860 891
861BB_HASHCHECK_FUNCTION = "sstate_checkhashes" 892BB_HASHCHECK_FUNCTION = "sstate_checkhashes"
@@ -930,7 +961,7 @@ def sstate_checkhashes(sq_data, d, siginfo=False, currentcount=0, summary=True,
930 961
931 localdata2 = bb.data.createCopy(localdata) 962 localdata2 = bb.data.createCopy(localdata)
932 srcuri = "file://" + sstatefile 963 srcuri = "file://" + sstatefile
933 localdata.setVar('SRC_URI', srcuri) 964 localdata2.setVar('SRC_URI', srcuri)
934 bb.debug(2, "SState: Attempting to fetch %s" % srcuri) 965 bb.debug(2, "SState: Attempting to fetch %s" % srcuri)
935 966
936 try: 967 try:
@@ -941,10 +972,11 @@ def sstate_checkhashes(sq_data, d, siginfo=False, currentcount=0, summary=True,
941 found.add(tid) 972 found.add(tid)
942 if tid in missed: 973 if tid in missed:
943 missed.remove(tid) 974 missed.remove(tid)
944 except: 975 except bb.fetch2.FetchError as e:
945 missed.add(tid) 976 missed.add(tid)
946 bb.debug(2, "SState: Unsuccessful fetch test for %s" % srcuri) 977 bb.debug(2, "SState: Unsuccessful fetch test for %s (%s)" % (srcuri, e))
947 pass 978 except Exception as e:
979 bb.error("SState: cannot test %s: %s" % (srcuri, e))
948 if len(tasklist) >= min_tasks: 980 if len(tasklist) >= min_tasks:
949 bb.event.fire(bb.event.ProcessProgress(msg, len(tasklist) - thread_worker.tasks.qsize()), d) 981 bb.event.fire(bb.event.ProcessProgress(msg, len(tasklist) - thread_worker.tasks.qsize()), d)
950 982
@@ -1006,6 +1038,7 @@ def sstate_checkhashes(sq_data, d, siginfo=False, currentcount=0, summary=True,
1006 bb.parse.siggen.checkhashes(sq_data, missed, found, d) 1038 bb.parse.siggen.checkhashes(sq_data, missed, found, d)
1007 1039
1008 return found 1040 return found
1041setscene_depvalid[vardepsexclude] = "SSTATE_EXCLUDEDEPS_SYSROOT"
1009 1042
1010BB_SETSCENE_DEPVALID = "setscene_depvalid" 1043BB_SETSCENE_DEPVALID = "setscene_depvalid"
1011 1044
@@ -1031,6 +1064,10 @@ def setscene_depvalid(task, taskdependees, notneeded, d, log=None):
1031 if taskdependees[task][1] == "do_populate_lic": 1064 if taskdependees[task][1] == "do_populate_lic":
1032 return True 1065 return True
1033 1066
1067 # We only need to trigger deploy_source_date_epoch through direct dependencies
1068 if taskdependees[task][1] == "do_deploy_source_date_epoch":
1069 return True
1070
1034 # stash_locale and gcc_stash_builddir are never needed as a dependency for built objects 1071 # stash_locale and gcc_stash_builddir are never needed as a dependency for built objects
1035 if taskdependees[task][1] == "do_stash_locale" or taskdependees[task][1] == "do_gcc_stash_builddir": 1072 if taskdependees[task][1] == "do_stash_locale" or taskdependees[task][1] == "do_gcc_stash_builddir":
1036 return True 1073 return True
@@ -1137,6 +1174,11 @@ python sstate_eventhandler() {
1137 os.utime(siginfo, None) 1174 os.utime(siginfo, None)
1138 except PermissionError: 1175 except PermissionError:
1139 pass 1176 pass
1177 except OSError as e:
1178 # Handle read-only file systems gracefully
1179 import errno
1180 if e.errno != errno.EROFS:
1181 raise e
1140 1182
1141} 1183}
1142 1184
@@ -1175,11 +1217,21 @@ python sstate_eventhandler2() {
1175 i = d.expand("${SSTATE_MANIFESTS}/index-" + a) 1217 i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
1176 if not os.path.exists(i): 1218 if not os.path.exists(i):
1177 continue 1219 continue
1220 manseen = set()
1221 ignore = []
1178 with open(i, "r") as f: 1222 with open(i, "r") as f:
1179 lines = f.readlines() 1223 lines = f.readlines()
1180 for l in lines: 1224 for l in reversed(lines):
1181 try: 1225 try:
1182 (stamp, manifest, workdir) = l.split() 1226 (stamp, manifest, workdir) = l.split()
1227 # The index may have multiple entries for the same manifest as the code above only appends
1228 # new entries and there may be an entry with matching manifest but differing version in stamp/workdir.
1229 # The last entry in the list is the valid one, any earlier entries with matching manifests
1230 # should be ignored.
1231 if manifest in manseen:
1232 ignore.append(l)
1233 continue
1234 manseen.add(manifest)
1183 if stamp not in stamps and stamp not in preservestamps and stamp in machineindex: 1235 if stamp not in stamps and stamp not in preservestamps and stamp in machineindex:
1184 toremove.append(l) 1236 toremove.append(l)
1185 if stamp not in seen: 1237 if stamp not in seen:
@@ -1210,6 +1262,8 @@ python sstate_eventhandler2() {
1210 1262
1211 with open(i, "w") as f: 1263 with open(i, "w") as f:
1212 for l in lines: 1264 for l in lines:
1265 if l in ignore:
1266 continue
1213 f.write(l) 1267 f.write(l)
1214 machineindex |= set(stamps) 1268 machineindex |= set(stamps)
1215 with open(mi, "w") as f: 1269 with open(mi, "w") as f: