Skip to content

Commit c6cebb6

Browse files
author
Florian Hines
committed
Write out ring.gz's in a safer fashion
Write the ring file to a temporary location first and then move it into place. This should help prevent issues like reading a partial ring file while a new instances is being written out. Change-Id: I28357a2f038a51cb9d823822b92f736dff033a9e
1 parent 86668aa commit c6cebb6

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

swift/common/ring/ring.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from io import BufferedReader
2525
from hashlib import md5
2626
from itertools import chain
27+
from tempfile import NamedTemporaryFile
2728

2829
from swift.common.utils import hash_path, validate_configuration, json
2930
from swift.common.ring.utils import tiers_for_dev
@@ -108,12 +109,18 @@ def save(self, filename):
108109
#
109110
# This only works on Python 2.7; on 2.6, we always get the
110111
# current time in the gzip output.
112+
tempf = NamedTemporaryFile(dir=".", prefix=filename, delete=False)
111113
try:
112-
gz_file = GzipFile(filename, 'wb', mtime=1300507380.0)
114+
gz_file = GzipFile(filename, mode='wb', fileobj=tempf,
115+
mtime=1300507380.0)
113116
except TypeError:
114-
gz_file = GzipFile(filename, 'wb')
117+
gz_file = GzipFile(filename, mode='wb', fileobj=tempf)
115118
self.serialize_v1(gz_file)
116119
gz_file.close()
120+
tempf.flush()
121+
os.fsync(tempf.fileno())
122+
tempf.close()
123+
os.rename(tempf.name, filename)
117124

118125
def to_dict(self):
119126
return {'devs': self.devs,

0 commit comments

Comments
 (0)