Stop race condition of reading a file before written to. Refs #1935.

This issue started to appear at some random times. After some hours narrowing down the problem I came to the conclusion that, on some systems, specially under heavy load the file was being read before it was fully written to. This behaviour was visible on a local vagrant machine, and also on travis-ci which also uses vagrant, so, it might actually be an issue with the vagrant(VirtualBox) filesystem access. Anyway, using the atomic open we seem to completely avoid this issue. Not closing ticket just yet so we can keep checking if this is really gone.
This commit is contained in:
Pedro Algarvio 2012-10-05 06:25:45 +01:00
parent 85fa73ec76
commit 1fe5d444a7

View File

@ -40,6 +40,7 @@ import salt.pillar
import salt.state import salt.state
import salt.runner import salt.runner
import salt.auth import salt.auth
import salt.utils.atomicfile
import salt.utils.event import salt.utils.event
import salt.utils.verify import salt.utils.verify
from salt.utils.debug import enable_sigusr1_handler from salt.utils.debug import enable_sigusr1_handler
@ -277,7 +278,6 @@ class Publisher(multiprocessing.Process):
super(Publisher, self).__init__() super(Publisher, self).__init__()
self.opts = opts self.opts = opts
def run(self): def run(self):
''' '''
Bind to the interface specified in the configuration file Bind to the interface specified in the configuration file
@ -400,7 +400,6 @@ class ReqServer(object):
self.publisher = Publisher(self.opts) self.publisher = Publisher(self.opts)
self.publisher.start() self.publisher.start()
def start_event_publisher(self): def start_event_publisher(self):
''' '''
Start the salt publisher interface Start the salt publisher interface
@ -809,11 +808,24 @@ class AESFuncs(object):
' attack').format(load['id']) ' attack').format(load['id'])
) )
return False return False
self.serial.dump(load['return'],
open(os.path.join(hn_dir, 'return.p'), 'w+')) self.serial.dump(
load['return'],
# Use atomic open here to avoid the file being read before it's
# completely written to. Refs #1935
salt.utils.atomicfile.atomic_open(
os.path.join(hn_dir, 'return.p'), 'w+'
)
)
if 'out' in load: if 'out' in load:
self.serial.dump(load['out'], self.serial.dump(
open(os.path.join(hn_dir, 'out.p'), 'w+')) load['out'],
# Use atomic open here to avoid the file being read before
# it's completely written to. Refs #1935
salt.utils.atomicfile.atomic_open(
os.path.join(hn_dir, 'out.p'), 'w+'
)
)
def _syndic_return(self, load): def _syndic_return(self, load):
''' '''
@ -898,7 +910,6 @@ class AESFuncs(object):
runner = salt.runner.Runner(opts) runner = salt.runner.Runner(opts)
return runner.run() return runner.run()
def minion_publish(self, clear_load): def minion_publish(self, clear_load):
''' '''
Publish a command initiated from a minion, this method executes minion Publish a command initiated from a minion, this method executes minion