[PATCH v2] localedata: Avoid concurrently written locales in gen-locale.sh

Florian Weimer <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Message-ID <[email protected]>
There is no cross-directory exclusion of concurrent $(gen-locales)
usage.  Parallel localedef calls can clobber locale data as it is
being loaded by tests.

With --no-hard-links, the separate touch invocation is now longer
necessary.

---
v2: Avoid mv options.  Probably more portable.
 localedata/gen-locale.sh | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/localedata/gen-locale.sh b/localedata/gen-locale.sh
index 4762c04284..d16dccc9ca 100644
--- a/localedata/gen-locale.sh
+++ b/localedata/gen-locale.sh
@@ -32,17 +32,26 @@ generate_locale ()
   out=$3
   flags=$4
   ret=0
+
+  # Use a staging area to avoid writing to locales concurrently.
+  # While this process is running, $$ is sufficiently unique.
+  # Use --no-hard-links to prevent localedef from accessing
+  # other staging areas.
+  stage="${common_objpfx}localedata/gen-locale.$$.tmp"
+
   ${localedef_before_env} ${run_program_env} I18NPATH=../localedata \
-	${localedef_after_env} $flags -f $charmap -i $input \
-	${common_objpfx}localedata/$out || ret=$?
-  if [ $ret -eq 0 ]; then
-    # The makefile checks the timestamp of the LC_CTYPE file,
-    # but localedef won't have touched it if it was able to
-    # hard-link it to an existing file.
-    touch ${common_objpfx}localedata/$out/LC_CTYPE
+	${localedef_after_env} $flags --no-hard-links -f $charmap -i $input \
+	$stage/$out || ret=$?
+  if [ $ret -eq 0 ] ; then
+      # Ignore errors in case some other process has created the same locale.
+      # This rename operation should be atomic, and it should fail if the
+      # $out locale already exists (rename fails with ENOTEMPTY).
+      mv $stage/$out ${common_objpfx}localedata/. 2>/dev/null || true
+      rm -rf $stage
   else
+    rm -rf $stage
     echo "Charmap: \"${charmap}\" Inputfile: \"${input}\"" \
-	 "Outputdir: \"${out}\" failed"
+	 "Outputdir: \"${out}\" failed (exit status $ret)"
     exit 1
   fi
 }

base-commit: f142bca0e6d9e501b8e704697a827d0b1c6d771e
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.