diff options
author | Mark Hatle <mark.hatle@amd.com> | 2024-07-19 13:58:17 -0500 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-07-22 16:53:06 +0100 |
commit | fa894486a99237b56469354c24ef913a96753aaf (patch) | |
tree | a63fcd70785348610d067aef0d367492b1d91b4e | |
parent | 15e5193e9f4790154890774a3326784a009dff68 (diff) | |
download | poky-fa894486a99237b56469354c24ef913a96753aaf.tar.gz |
package.py: Fix static library processing
When PACKAGE_STRIP_STATIC is enabled the system did not pay attention to
hardlinks. This could trigger a race condition during stripping of static
libraries where multiple strips (through hardlinks) could run at the same
time triggering a truncated or modified file error.
The hardlink breaking code is based on the existing code for elf files, but
due to the nature of the symlinks needed to be done in a separate block of
code.
Add support for static-library debugfs hardlinking through the existing
inode processing code.
Print a note to the logs if the link target can't be found. This isn't
strictly an error, but may be useful for debugging an issue where a file
isn't present.
(From OE-Core rev: ff371d69f60a1529ed456acb7d8e9305242e74bd)
Signed-off-by: Mark Hatle <mark.hatle@amd.com>
Signed-off-by: Mark Hatle <mark.hatle@kernel.crashing.org>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | meta/lib/oe/package.py | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/meta/lib/oe/package.py b/meta/lib/oe/package.py index 235f2d6c40..c213a9a3ca 100644 --- a/meta/lib/oe/package.py +++ b/meta/lib/oe/package.py | |||
@@ -1079,6 +1079,7 @@ def process_split_and_strip_files(d): | |||
1079 | d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'): | 1079 | d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'): |
1080 | checkelf = {} | 1080 | checkelf = {} |
1081 | checkelflinks = {} | 1081 | checkelflinks = {} |
1082 | checkstatic = {} | ||
1082 | for root, dirs, files in cpath.walk(dvar): | 1083 | for root, dirs, files in cpath.walk(dvar): |
1083 | for f in files: | 1084 | for f in files: |
1084 | file = os.path.join(root, f) | 1085 | file = os.path.join(root, f) |
@@ -1092,10 +1093,6 @@ def process_split_and_strip_files(d): | |||
1092 | if file in skipfiles: | 1093 | if file in skipfiles: |
1093 | continue | 1094 | continue |
1094 | 1095 | ||
1095 | if oe.package.is_static_lib(file): | ||
1096 | staticlibs.append(file) | ||
1097 | continue | ||
1098 | |||
1099 | try: | 1096 | try: |
1100 | ltarget = cpath.realpath(file, dvar, False) | 1097 | ltarget = cpath.realpath(file, dvar, False) |
1101 | s = cpath.lstat(ltarget) | 1098 | s = cpath.lstat(ltarget) |
@@ -1107,6 +1104,13 @@ def process_split_and_strip_files(d): | |||
1107 | continue | 1104 | continue |
1108 | if not s: | 1105 | if not s: |
1109 | continue | 1106 | continue |
1107 | |||
1108 | if oe.package.is_static_lib(file): | ||
1109 | # Use a reference of device ID and inode number to identify files | ||
1110 | file_reference = "%d_%d" % (s.st_dev, s.st_ino) | ||
1111 | checkstatic[file] = (file, file_reference) | ||
1112 | continue | ||
1113 | |||
1110 | # Check its an executable | 1114 | # Check its an executable |
1111 | if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) \ | 1115 | if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) \ |
1112 | or (s[stat.ST_MODE] & stat.S_IXOTH) \ | 1116 | or (s[stat.ST_MODE] & stat.S_IXOTH) \ |
@@ -1171,6 +1175,27 @@ def process_split_and_strip_files(d): | |||
1171 | # Modified the file so clear the cache | 1175 | # Modified the file so clear the cache |
1172 | cpath.updatecache(file) | 1176 | cpath.updatecache(file) |
1173 | 1177 | ||
1178 | # Do the same hardlink processing as above, but for static libraries | ||
1179 | results = list(checkstatic.keys()) | ||
1180 | |||
1181 | # As above, sort the results. | ||
1182 | results.sort(key=lambda x: x[0]) | ||
1183 | |||
1184 | for file in results: | ||
1185 | # Use a reference of device ID and inode number to identify files | ||
1186 | file_reference = checkstatic[file][1] | ||
1187 | if file_reference in inodes: | ||
1188 | os.unlink(file) | ||
1189 | os.link(inodes[file_reference][0], file) | ||
1190 | inodes[file_reference].append(file) | ||
1191 | else: | ||
1192 | inodes[file_reference] = [file] | ||
1193 | # break hardlink | ||
1194 | bb.utils.break_hardlinks(file) | ||
1195 | staticlibs.append(file) | ||
1196 | # Modified the file so clear the cache | ||
1197 | cpath.updatecache(file) | ||
1198 | |||
1174 | def strip_pkgd_prefix(f): | 1199 | def strip_pkgd_prefix(f): |
1175 | nonlocal dvar | 1200 | nonlocal dvar |
1176 | 1201 | ||
@@ -1209,11 +1234,24 @@ def process_split_and_strip_files(d): | |||
1209 | dest = dv["libdir"] + os.path.dirname(src) + dv["dir"] + "/" + os.path.basename(target) + dv["append"] | 1234 | dest = dv["libdir"] + os.path.dirname(src) + dv["dir"] + "/" + os.path.basename(target) + dv["append"] |
1210 | fpath = dvar + dest | 1235 | fpath = dvar + dest |
1211 | ftarget = dvar + dv["libdir"] + os.path.dirname(target) + dv["dir"] + "/" + os.path.basename(target) + dv["append"] | 1236 | ftarget = dvar + dv["libdir"] + os.path.dirname(target) + dv["dir"] + "/" + os.path.basename(target) + dv["append"] |
1212 | bb.utils.mkdirhier(os.path.dirname(fpath)) | 1237 | if os.access(ftarget, os.R_OK): |
1213 | # Only one hardlink of separated debug info file in each directory | 1238 | bb.utils.mkdirhier(os.path.dirname(fpath)) |
1214 | if not os.access(fpath, os.R_OK): | 1239 | # Only one hardlink of separated debug info file in each directory |
1215 | #bb.note("Link %s -> %s" % (fpath, ftarget)) | 1240 | if not os.access(fpath, os.R_OK): |
1216 | os.link(ftarget, fpath) | 1241 | #bb.note("Link %s -> %s" % (fpath, ftarget)) |
1242 | os.link(ftarget, fpath) | ||
1243 | elif (d.getVar('PACKAGE_DEBUG_STATIC_SPLIT') == '1'): | ||
1244 | deststatic = dv["staticlibdir"] + os.path.dirname(src) + dv["staticdir"] + "/" + os.path.basename(file) + dv["staticappend"] | ||
1245 | fpath = dvar + deststatic | ||
1246 | ftarget = dvar + dv["staticlibdir"] + os.path.dirname(target) + dv["staticdir"] + "/" + os.path.basename(target) + dv["staticappend"] | ||
1247 | if os.access(ftarget, os.R_OK): | ||
1248 | bb.utils.mkdirhier(os.path.dirname(fpath)) | ||
1249 | # Only one hardlink of separated debug info file in each directory | ||
1250 | if not os.access(fpath, os.R_OK): | ||
1251 | #bb.note("Link %s -> %s" % (fpath, ftarget)) | ||
1252 | os.link(ftarget, fpath) | ||
1253 | else: | ||
1254 | bb.note("Unable to find inode link target %s" % (target)) | ||
1217 | 1255 | ||
1218 | # Create symlinks for all cases we were able to split symbols | 1256 | # Create symlinks for all cases we were able to split symbols |
1219 | for file in symlinks: | 1257 | for file in symlinks: |