diff options
Diffstat (limited to 'meta/classes/sstate.bbclass')
-rw-r--r-- | meta/classes/sstate.bbclass | 98 |
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 \ | |||
123 | python () { | 123 | python () { |
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 | ||
484 | def sstate_clean_manifest(manifest, d, prefix=None): | 484 | def 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 | ||
639 | def sstate_package(ss, d): | 641 | def 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 | ||
732 | sstate_package[vardepsexclude] += "SSTATE_SIG_KEY" | ||
733 | |||
707 | def pstaging_fetch(sstatefetch, d): | 734 | def pstaging_fetch(sstatefetch, d): |
708 | import bb.fetch2 | 735 | import bb.fetch2 |
709 | 736 | ||
@@ -787,7 +814,7 @@ sstate_task_postfunc[dirs] = "${WORKDIR}" | |||
787 | sstate_create_package () { | 814 | sstate_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 | ||
827 | python sstate_sign_package () { | 858 | python sstate_sign_package () { |
@@ -850,12 +881,12 @@ python sstate_report_unihash() { | |||
850 | # | 881 | # |
851 | sstate_unpack_package () { | 882 | sstate_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 | ||
861 | BB_HASHCHECK_FUNCTION = "sstate_checkhashes" | 892 | BB_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 |
1041 | setscene_depvalid[vardepsexclude] = "SSTATE_EXCLUDEDEPS_SYSROOT" | ||
1009 | 1042 | ||
1010 | BB_SETSCENE_DEPVALID = "setscene_depvalid" | 1043 | BB_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: |