Skip to content

Commit 2014484

Browse files
committed
hw-mgmt: scripts: Make creation of parsed VPD files atomic
Fix VPD parsing script to create the output file atomically, so that file always appears complete or not at all. This ensures that other processes won't see incomplete data. Bug: 4738257, 4502950, 4499192 Signed-off-by: Felix Radensky <[email protected]>
1 parent ac5e080 commit 2014484

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

usr/usr/bin/hw-management-vpd-parser.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -744,19 +744,37 @@ def save_fru(fru_dict, out_filename):
744744
@param out_filename: output filename
745745
@return: None
746746
"""
747+
# Get the directory of the output file for the temporary file
748+
out_dir = os.path.dirname(out_filename) or '.'
749+
tmp_filename = None
750+
747751
try:
748-
out_file = open(out_filename, 'w+')
749-
except IOError as err:
752+
# Create a temporary file in the same directory as the target file
753+
# This ensures the rename operation is atomic (same filesystem)
754+
with tempfile.NamedTemporaryFile(mode='w', dir=out_dir, delete=False) as tmp_file:
755+
tmp_filename = tmp_file.name
756+
757+
# Write all FRU data to the temporary file
758+
for item in fru_dict['items']:
759+
if item[0]:
760+
tmp_file.write("{:<25}{}\n".format(item[0] + ":", str(item[1]).rstrip()))
761+
else:
762+
tmp_file.write("{}\n".format(str(item[1]).rstrip()))
763+
764+
# Atomically rename the temporary file to the target filename
765+
# On POSIX systems, this is an atomic operation
766+
os.replace(tmp_filename, out_filename)
767+
768+
except (IOError, OSError) as err:
750769
print("I/O error({0}): {1} with log file {2}".format(err.errno,
751770
err.strerror,
752771
out_filename))
753-
for item in fru_dict['items']:
754-
if item[0]:
755-
out_file.write("{:<25}{}\n".format(item[0] + ":", str(item[1]).rstrip()))
756-
else:
757-
out_file.write("{}\n".format(str(item[1]).rstrip()))
758-
759-
out_file.close()
772+
# Clean up temporary file if it exists
773+
if tmp_filename and os.path.exists(tmp_filename):
774+
try:
775+
os.remove(tmp_filename)
776+
except OSError:
777+
pass
760778

761779

762780
def load_fru_bin(file_name):

0 commit comments

Comments
 (0)