bin/182098: [patch] Change kldxref fts_open ordering so it produces a consistent linker.hints between machines of the same architecture.
Derek Schrock
dereks at lifeofadishwasher.com
Sat Sep 14 19:40:00 UTC 2013
>Number: 182098
>Category: bin
>Synopsis: [patch] Change kldxref fts_open ordering so it produces a consistent linker.hints between machines of the same architecture.
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Sat Sep 14 19:40:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator: Derek Schrock
>Release: 9.1-RELEASE-p7
>Organization:
>Environment:
FreeBSD ircbsd 9.1-RELEASE-p7 FreeBSD 9.1-RELEASE-p7 #0: Mon Sep 9 21:34:37 UTC 2013 root at amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64
>Description:
Currently there an issue with linker.hints being different between machines that create binary update for freebsd-update.
http://www.freebsd.org/cgi/query-pr.cgi?pr=amd64/178247
Use freebsd-update to update:
$ freebsd-update fetch
Looking up update.FreeBSD.org mirrors... 5 mirrors found.
Fetching metadata signature for 9.1-RELEASE from update2.freebsd.org... done.
Fetching metadata index... done.
Inspecting system... done.
Preparing to download files... done.
The following files will be updated as part of updating to 9.1-RELEASE-p7:
/boot/kernel/linker.hints
$ freebsd-update install
Installing updates... done.
$ freebsd-update fetch
Looking up update.FreeBSD.org mirrors... 5 mirrors found.
Fetching metadata signature for 9.1-RELEASE from update5.freebsd.org... done.
Fetching metadata index... done.
Inspecting system... done.
Preparing to download files... done.
The following files will be updated as part of updating to 9.1-RELEASE-p7:
/boot/kernel/linker.hints
Looking at /boot/kernel on two different systems:
Host A /boot/kernel/:
$ sha256 /boot/kernel/* | sha256
6193fe0ea115ae745f8b99273906892d5a8714d7fd55f506f24064ef0396f1eb
Host B /boot/kernel:
$ sha256 /boot/kernel/* | sha256
6193fe0ea115ae745f8b99273906892d5a8714d7fd55f506f24064ef0396f1eb
'kldxref /boot/kernel/' will produce different linker.hints due to the way the fts_open() traverses the file system:
Host A:
$ kldxref /boot/kernel/
$ sha256 /boot/kernel/linker.hints
SHA256 (/boot/kernel/linker.hints) = 3deeb3eb746b40b009f67238b924c32d1a6d0d586f127aded45bef0010345290
Host B:
$ kldxref /boot/kernel/
$ sha256 /boot/kernel/linker.hints
SHA256 (/boot/kernel/linker.hints) = ec6c0c80e745371f83faa100f1fe1a36062903c527d20dce7e0161ce26c82e54
If you change fts_open() to order the files in /boot/kernel/ the same linker.hints should be created between systems:
Host A:
$ ./patched.kldxref /boot/kernel/
$ sha256 /boot/kernel/linker.hints
SHA256 (/boot/kernel/linker.hints) = 2bda1a7568108dfb511d5156efce2d4df173dc8e91124e0c9300a5fef90218c8
$ sha256 /boot/kernel/linker.hints
SHA256 (/boot/kernel/linker.hints) = 2bda1a7568108dfb511d5156efce2d4df173dc8e91124e0c9300a5fef90218c8
>How-To-Repeat:
Find a system the produces a different linker.hints than another system's.
Host A:
$ kldxref /boot/kernel/
$ sha256 /boot/kernel/linker.hints
SHA256 (/boot/kernel/linker.hints) = 3deeb3eb746b40b009f67238b924c32d1a6d0d586f127aded45bef0010345290
Host B:
$ kldxref /boot/kernel/
$ sha256 /boot/kernel/linker.hints
SHA256 (/boot/kernel/linker.hints) = ec6c0c80e745371f83faa100f1fe1a36062903c527d20dce7e0161ce26c82e54
>Fix:
patch kldxref.c to use fts_open() with a compare function to order the filenames.
(another possible fix would be to not include linker.hints in freebsd-update binary updates)
Patch attached with submission follows:
--- kldxref.c.old 2013-09-14 00:31:05.000000000 -0400
+++ kldxref.c 2013-09-14 14:53:53.000000000 -0400
@@ -275,6 +275,16 @@
exit(1);
}
+int
+compare(const FTSENT* const* a, const FTSENT* const* b)
+{
+ const char *pa = (const char *)((*a)->fts_name);
+ const char *pb = (const char *)((*b)->fts_name);
+ size_t as = (*a)->fts_namelen;
+ size_t bs = (*b)->fts_namelen;
+ return strncmp(pa, pb, as > bs ? bs : as);
+}
+
int
main(int argc, char *argv[])
{
@@ -316,7 +326,7 @@
err(1, "%s", argv[0]);
}
- ftsp = fts_open(argv, fts_options, 0);
+ ftsp = fts_open(argv, fts_options, compare);
if (ftsp == NULL)
exit(1);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list