On 25/05/11 14:46, Simon Kelley wrote:
> cp file file.new
> mv file.new file
> 
> has the desired effect and atomically changes the mtime without a race
> window where the contents of file may be invalid.


The current code (i.e., in my first patch) doesn't suffer from a race
because it acts upon a temporary file before the latter is mv'ed
(atomically) to the active name.

I was thinking about this issue last night and had the idea of just
checking the time before writing the temporary file.  This could be
done with "date", I realize, but can also be done with bash's printf,
as in the attached patch, which is a bit shorter than the previous one.
-- 
Thomas
--- dnsmasq_ORIG	2011-02-20 03:21:14.000000000 +0100
+++ dnsmasq	2011-05-25 15:26:06.146862344 +0200
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 # Script to update the resolver list for dnsmasq
 #
@@ -8,12 +8,10 @@
 #
 # Assumption: On entry, PWD contains the resolv.conf-type files
 #
-# Depends: resolvconf (>= 1.14)
+# Requires bash because it uses a non-POSIX printf extension.
 #
 # Licensed under the GNU GPL.  See /usr/share/common-licenses/GPL.
 #
-# History
-# June 2003 - June 2004: Written by Thomas Hood <jdth...@yahoo.co.uk>
 
 set -e
 
@@ -55,16 +53,18 @@
 	NMSRVRS="$RSLT"
 fi
 
+# Dnsmasq uses the mtime of $RSLVRLIST_FILE, with a resolution of one second,
+# to detect changes in the file. This means that if a resolvconf update occurs
+# within one second of the previous one then dnsmasq may fail to notice the
+# more recent change.  To work around this problem we sleep here to ensure
+# that the new mtime is different.
+if [ -f "$RSLVRLIST_FILE" ] && [ "$(ls -go --time-style='+%s' "$RSLVRLIST_FILE" | { read p h s t n ; echo "$t" ; })" = "$(printf '%(%s)T' "-1")" ] ; then
+	sleep 1
+fi
+
 clean_up() { rm -f "$TMP_FILE" ; }
 trap clean_up EXIT
 : >| "$TMP_FILE"
 for N in $NMSRVRS ; do echo "nameserver $N" >> "$TMP_FILE" ; done
 mv -f "$TMP_FILE" "$RSLVRLIST_FILE"
 
-# dnsmasq uses the mtime of the file to detect changes. This has a resolution of one second, 
-# so it's possible that if two or more changes occur rapidly, the second change could 
-# be missed. We avoid this possibility by delaying here.
-sleep 1
-
- 
-

Reply via email to