about summary refs log tree commit diff
path: root/locale/programs/locfile.c
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@redhat.com>2018-11-26 09:51:51 -0500
committerCarlos O'Donell <carlos@redhat.com>2018-12-03 10:15:39 -0500
commit8cebd4ffe67bf94508809ea0caa02a4f1d52e8b1 (patch)
tree37941e21ff2e02a3d6318eceeef5bc7d565215ae /locale/programs/locfile.c
parentc22e4c2a1431c5e77bf4288d35bf7629f2f093aa (diff)
downloadglibc-8cebd4ffe67bf94508809ea0caa02a4f1d52e8b1.tar.gz
glibc-8cebd4ffe67bf94508809ea0caa02a4f1d52e8b1.tar.xz
glibc-8cebd4ffe67bf94508809ea0caa02a4f1d52e8b1.zip
Add --no-hard-links option to localedef (bug 23923)
Downstream distributions need consistent sets of hardlinks in
order for rpm to operate effectively. This means that even if
locales are built with a high level of parallelism that the
resulting files need to have consistent hardlink counts. The only
way to achieve this is with a post-install hardlink pass using a
program like 'hardlink' (shipped in Fedora).

If the downstream distro wants to post-process the hardlinks then
the time spent in localedef looking up sibling directories and
processing hardlinks is wasted effort.

To optimize the build and install pass we add a --no-hard-links
option to localedef to avoid doing the hardlink optimziation for
size.

Tested on x86_64 with 'make localedata/install-locale-files'
before and after. Without the patch we have files with 100+
hardlink counts. After the patch and running with --no-hard-links
all link counts are 1. This patch also alters the convenience
target 'make localedata/install-locale-files' to use the new
option.

Signed-off-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'locale/programs/locfile.c')
-rw-r--r--locale/programs/locfile.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c
index 32e5f761f2..1555231deb 100644
--- a/locale/programs/locfile.c
+++ b/locale/programs/locfile.c
@@ -702,7 +702,7 @@ write_locale_data (const char *output_path, int catidx, const char *category,
   size_t cnt, step, maxiov;
   int fd;
   char *fname;
-  const char **other_paths;
+  const char **other_paths = NULL;
   uint32_t header[2];
   size_t n_elem;
   struct iovec vec[3];
@@ -827,9 +827,22 @@ failure while writing data for category `%s'"), category);
 
   close (fd);
 
-  /* Compare the file with the locale data files for the same category in
-     other locales, and see if we can reuse it, to save disk space.  */
-  other_paths = siblings (output_path);
+  /* Compare the file with the locale data files for the same category
+     in other locales, and see if we can reuse it, to save disk space.
+     If the user specified --no-hard-links to localedef then hard_links
+     is false, other_paths remains NULL and we skip the optimization
+     below.  The use of --no-hard-links is distribution specific since
+     some distros have post-processing hard-link steps and so doing this
+     here is a waste of time.  Worse than a waste of time in rpm-based
+     distributions it can result in build determinism issues from
+     build-to-build since some files may get a hard link in one pass but
+     not in another (if the files happened to be created in parallel).  */
+  if (hard_links)
+    other_paths = siblings (output_path);
+
+  /* If there are other paths, then walk the sibling paths looking for
+     files with the same content so we can hard link and reduce disk
+     space usage.  */
   if (other_paths != NULL)
     {
       struct stat64 fname_stat;