Skip to content

Commit 6e5a7ad

Browse files
committed
hw-mgmgt: script: Fix race conditions for write in thermal updater
Prevent race conditions by using atomic file writes. Replace open()/write() with atomic_file_write() to ensure readers never see empty or partial content when thermal attributes are updated. Bug: 4647791 Signed-off-by: Oleksandr Shamray <[email protected]>
1 parent 8075535 commit 6e5a7ad

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

usr/usr/bin/hw_management_lib.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,31 @@
3939
import threading
4040
import time
4141
import json
42+
import tempfile
4243
from typing import Any, Dict, Set, Optional
4344

4445

4546
# ----------------------------------------------------------------------
4647

48+
def atomic_file_write(file_name, value):
49+
"""
50+
@summary:
51+
Write value to file atomically
52+
@param file_name: name of file
53+
@param value: value to write
54+
"""
55+
fd, f_path_tmp = tempfile.mkstemp(dir=os.path.dirname(file_name), prefix='.tmp_')
56+
try:
57+
with os.fdopen(fd, 'w', encoding="utf-8") as f:
58+
f.write("{}".format(value))
59+
os.replace(f_path_tmp, file_name) # Atomic on POSIX
60+
except Exception as e:
61+
os.unlink(f_path_tmp) # Cleanup on failure
62+
raise Exception(f"Error writing {file_name}: {e}")
63+
64+
# ----------------------------------------------------------------------
65+
66+
4767
def current_milli_time():
4868
"""
4969
@summary:

usr/usr/bin/hw_management_thermal_updater.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
import re
5353
import argparse
5454
import traceback
55-
from hw_management_lib import HW_Mgmt_Logger as Logger
55+
from hw_management_lib import HW_Mgmt_Logger as Logger, atomic_file_write
5656
from collections import Counter
5757
from hw_management_platform_config import (
5858
PLATFORM_CONFIG,
@@ -225,8 +225,8 @@ def asic_temp_reset(asic_name, f_asic_src_path):
225225
}
226226
for suffix, value in file_paths.items():
227227
f_name = "/var/run/hw-management/thermal/{}{}".format(asic_name, suffix)
228-
with open(f_name, 'w', encoding="utf-8") as f:
229-
f.write("{}\n".format(value))
228+
atomic_file_write(f_name, str(value) + "\n")
229+
230230

231231
# ----------------------------------------------------------------------
232232

@@ -310,9 +310,11 @@ def asic_temp_populate(arg_list, arg):
310310
# Write the temperature data to files
311311
for suffix, value in file_paths.items():
312312
f_name = "/var/run/hw-management/thermal/{}{}".format(asic_name, suffix)
313-
with open(f_name, 'w', encoding="utf-8") as f:
314-
f.write("{}\n".format(value))
315-
LOGGER.debug(f"Write {asic_name}{suffix}: {value}")
313+
try:
314+
atomic_file_write(f_name, str(value) + "\n")
315+
except Exception as e:
316+
LOGGER.error(f"Error writing {f_name}: {e}")
317+
continue
316318

317319
# ----------------------------------------------------------------------
318320

@@ -435,9 +437,11 @@ def module_temp_populate(arg_list, _dummy):
435437
for suffix, value in file_paths.items():
436438
f_name = "/var/run/hw-management/thermal/{}{}".format(module_name, suffix)
437439
if value is not None:
438-
with open(f_name, 'w', encoding="utf-8") as f:
439-
f.write("{}\n".format(value))
440-
LOGGER.debug(f"Write {module_name}{suffix}: {value}")
440+
try:
441+
atomic_file_write(f_name, str(value) + "\n")
442+
except Exception as e:
443+
LOGGER.error(f"Error writing {f_name}: {e}")
444+
continue
441445

442446
return
443447

0 commit comments

Comments
 (0)