diff options
author | Ed Bartosh <ed.bartosh@linux.intel.com> | 2015-05-14 19:01:41 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-05-15 18:13:38 +0100 |
commit | 59e4f9fc1255b7888ffccc87ce6cc3f2b8bf98c3 (patch) | |
tree | b07193764a8aa28e525449ba2866cb0a92e4e54c /meta | |
parent | 4dc652a0c33321f5079448b0f182c8b8f7b2b4f6 (diff) | |
download | poky-59e4f9fc1255b7888ffccc87ce6cc3f2b8bf98c3.tar.gz |
split_and_strip_files: regroup hardlinks to make build deterministic
Reverted 7c0fd561bad0250a00cef63e3d787573112a59cf
Created separate group of hardlinks for the files inside
the same package. This should prevent stripped files to be
populated outside of package directories.
This turns out not to be straightforward and has overlap with the
other hardlink handling code in this area. The code is condensed
into a more concise and documented form.
[Original patch from Ed with tweaks from RP]
[YOCTO #7586]
(From OE-Core master rev: 82d00f7254b7d3bb6a167d675d798134884d1b19)
(From OE-Core rev: 2abacf00ee3f60735bf7c0dc7130c72267822b30)
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r-- | meta/classes/package.bbclass | 48 | ||||
-rw-r--r-- | meta/lib/oe/package.py | 3 |
2 files changed, 27 insertions, 24 deletions
diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass index 5558d0d100..d731757f14 100644 --- a/meta/classes/package.bbclass +++ b/meta/classes/package.bbclass | |||
@@ -875,8 +875,8 @@ python split_and_strip_files () { | |||
875 | # | 875 | # |
876 | elffiles = {} | 876 | elffiles = {} |
877 | symlinks = {} | 877 | symlinks = {} |
878 | hardlinks = {} | ||
879 | kernmods = [] | 878 | kernmods = [] |
879 | inodes = {} | ||
880 | libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir", True)) | 880 | libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir", True)) |
881 | baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir", True)) | 881 | baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir", True)) |
882 | if (d.getVar('INHIBIT_PACKAGE_STRIP', True) != '1'): | 882 | if (d.getVar('INHIBIT_PACKAGE_STRIP', True) != '1'): |
@@ -914,6 +914,7 @@ python split_and_strip_files () { | |||
914 | #bb.note("Sym: %s (%d)" % (ltarget, isELF(ltarget))) | 914 | #bb.note("Sym: %s (%d)" % (ltarget, isELF(ltarget))) |
915 | symlinks[file] = target | 915 | symlinks[file] = target |
916 | continue | 916 | continue |
917 | |||
917 | # It's a file (or hardlink), not a link | 918 | # It's a file (or hardlink), not a link |
918 | # ...but is it ELF, and is it already stripped? | 919 | # ...but is it ELF, and is it already stripped? |
919 | elf_file = isELF(file) | 920 | elf_file = isELF(file) |
@@ -925,28 +926,30 @@ python split_and_strip_files () { | |||
925 | msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn) | 926 | msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn) |
926 | package_qa_handle_error("already-stripped", msg, d) | 927 | package_qa_handle_error("already-stripped", msg, d) |
927 | continue | 928 | continue |
928 | # Check if it's a hard link to something else | 929 | |
929 | if s.st_nlink > 1: | 930 | # At this point we have an unstripped elf file. We need to: |
930 | file_reference = "%d_%d" % (s.st_dev, s.st_ino) | 931 | # a) Make sure any file we strip is not hardlinked to anything else outside this tree |
931 | # Hard link to something else | 932 | # b) Only strip any hardlinked file once (no races) |
932 | hardlinks[file] = file_reference | 933 | # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks |
933 | continue | 934 | |
934 | elffiles[file] = elf_file | 935 | # Use a reference of device ID and inode number to indentify files |
936 | file_reference = "%d_%d" % (s.st_dev, s.st_ino) | ||
937 | if file_reference in inodes: | ||
938 | os.unlink(file) | ||
939 | os.link(inodes[file_reference][0], file) | ||
940 | inodes[file_reference].append(file) | ||
941 | else: | ||
942 | inodes[file_reference] = [file] | ||
943 | # break hardlink | ||
944 | bb.utils.copyfile(file, file) | ||
945 | elffiles[file] = elf_file | ||
946 | # Modified the file so clear the cache | ||
947 | cpath.updatecache(file) | ||
935 | 948 | ||
936 | # | 949 | # |
937 | # First lets process debug splitting | 950 | # First lets process debug splitting |
938 | # | 951 | # |
939 | if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT', True) != '1'): | 952 | if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT', True) != '1'): |
940 | hardlinkmap = {} | ||
941 | # For hardlinks, process only one of the files | ||
942 | for file in hardlinks: | ||
943 | file_reference = hardlinks[file] | ||
944 | if file_reference not in hardlinkmap: | ||
945 | # If this is a new file, add it as a reference, and | ||
946 | # update it's type, so we can fall through and split | ||
947 | elffiles[file] = isELF(file) | ||
948 | hardlinkmap[file_reference] = file | ||
949 | |||
950 | for file in elffiles: | 953 | for file in elffiles: |
951 | src = file[len(dvar):] | 954 | src = file[len(dvar):] |
952 | dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend | 955 | dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend |
@@ -959,13 +962,14 @@ python split_and_strip_files () { | |||
959 | splitdebuginfo(file, fpath, debugsrcdir, sourcefile, d) | 962 | splitdebuginfo(file, fpath, debugsrcdir, sourcefile, d) |
960 | 963 | ||
961 | # Hardlink our debug symbols to the other hardlink copies | 964 | # Hardlink our debug symbols to the other hardlink copies |
962 | for file in hardlinks: | 965 | for ref in inodes: |
963 | if file not in elffiles: | 966 | if len(inodes[ref]) == 1: |
967 | continue | ||
968 | for file in inodes[ref][1:]: | ||
964 | src = file[len(dvar):] | 969 | src = file[len(dvar):] |
965 | dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend | 970 | dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend |
966 | fpath = dvar + dest | 971 | fpath = dvar + dest |
967 | file_reference = hardlinks[file] | 972 | target = inodes[ref][0][len(dvar):] |
968 | target = hardlinkmap[file_reference][len(dvar):] | ||
969 | ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend | 973 | ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend |
970 | bb.utils.mkdirhier(os.path.dirname(fpath)) | 974 | bb.utils.mkdirhier(os.path.dirname(fpath)) |
971 | #bb.note("Link %s -> %s" % (fpath, ftarget)) | 975 | #bb.note("Link %s -> %s" % (fpath, ftarget)) |
diff --git a/meta/lib/oe/package.py b/meta/lib/oe/package.py index 8bc56c6e88..ea6feaaea4 100644 --- a/meta/lib/oe/package.py +++ b/meta/lib/oe/package.py | |||
@@ -30,8 +30,7 @@ def runstrip(arg): | |||
30 | elif elftype & 8 or elftype & 4: | 30 | elif elftype & 8 or elftype & 4: |
31 | extraflags = "--remove-section=.comment --remove-section=.note" | 31 | extraflags = "--remove-section=.comment --remove-section=.note" |
32 | 32 | ||
33 | # Use mv to break hardlinks | 33 | stripcmd = "'%s' %s '%s'" % (strip, extraflags, file) |
34 | stripcmd = "'%s' %s '%s' -o '%s.tmp' && chown --reference='%s' '%s.tmp' && mv '%s.tmp' '%s'" % (strip, extraflags, file, file, file, file, file, file) | ||
35 | bb.debug(1, "runstrip: %s" % stripcmd) | 34 | bb.debug(1, "runstrip: %s" % stripcmd) |
36 | 35 | ||
37 | ret = subprocess.call(stripcmd, shell=True) | 36 | ret = subprocess.call(stripcmd, shell=True) |