ctdb-scripts: Use more unique temporary file names
authorMartin Schwenke <martin@meltin.net>
Thu, 10 Dec 2015 04:03:46 +0000 (15:03 +1100)
committerMichael Adam <obnox@samba.org>
Tue, 12 Jan 2016 18:16:18 +0000 (19:16 +0100)
Consider this sequence of events:

1. Instance of script running update_tickles() hangs
2. Script debugging is launched asynchronously
3. New instance of script is launched, creates temporary file(s)
4. Original hung script makes progress before asynchronous script
   debugging kills it, so it removes temporary file(s)
5. New instance of script produces error due to missing files(s)

This is obviously rare.

Use more unique filenames to avoid step (4) removing the file(s)
belonging to other instances of the script.

This requires some extra cleanup to avoid too many temporary files
(which is why unique filenames were not originally usd).  It is
sufficient to remove files modified at least 10 minutes ago.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Michael Adam <obnox@samba.org>
ctdb/config/functions

index b41337ffbf7040c6aab6e9cc412a4bf810f8158e..68e53abf74b97d91ed7f9e50540925b58b1be35b 100755 (executable)
@@ -1082,15 +1082,18 @@ update_tickles ()
        # IPs as a regexp choice
        _ipschoice="($(echo $_ips | sed -e 's/ /|/g' -e 's/\./\\\\./g'))"
 
-       # Record connections to our public IPs in a temporary file
-       _my_connections="${tickledir}/${_port}.connections"
+       # Record connections to our public IPs in a temporary file.
+       # This temporary file is in CTDB's private state directory and
+       # $$ is used to avoid a very rare race involving CTDB's script
+       # debugging.  No security issue, nothing to see here...
+       _my_connections="${tickledir}/${_port}.connections.$$"
        netstat -tn |
        awk -v destpat="^${_ipschoice}:${_port}\$" \
          '$1 == "tcp" && $6 == "ESTABLISHED" && $4 ~ destpat {print $5, $4}' |
        sort >"$_my_connections"
 
        # Record our current tickles in a temporary file
-       _my_tickles="${tickledir}/${_port}.tickles"
+       _my_tickles="${tickledir}/${_port}.tickles.$$"
        for _i in $_ips ; do
                ctdb -X gettickles $_i $_port |
                awk -F'|' 'NR > 1 { printf "%s:%s %s:%s\n", $2, $3, $4, $5 }'
@@ -1109,7 +1112,10 @@ update_tickles ()
                ctdb deltickle $_src $_dst
        done
 
-       rm -f "$_my_connections" "$_my_tickles" 
+       rm -f "$_my_connections" "$_my_tickles"
+
+       # Remove stale files from killed scripts
+       find "$tickledir" -type f -mmin +10 | xargs -r rm
 }
 
 ########################################################