Skip to content

[database] Publish database_config.json atomically - #29464

Merged
yxieca merged 1 commit into
sonic-net:masterfrom
chartsai-nvidia:chartsai/202605-parseDatabaseConfig
Sep 22, 2026
Merged

yxieca merged 1 commit into
sonic-net:masterfrom
chartsai-nvidia:chartsai/202605-parseDatabaseConfig

Conversation

@chartsai-nvidia

Copy link
Copy Markdown
Contributor

Why I did it

database_config.json is read concurrently during database startup. PR
#28343 made the initial publication
atomic, but three later publication paths remained non-atomic and could truncate a live JSON file
before writing its replacement. This PR extends atomic publication to those remaining known paths.

Instrumentation on DUT measured a 285 us truncate-and-rewrite window in the live-file
update_chassisdb_config path. The controlled 202605 A/B test reproduced the empty-read failure
with the installed writer and eliminated it with the atomic writer.

Work item tracking
  • Microsoft ADO (number only): N/A

How I did it

  • Copy /etc/sonic/database_config*.json to a sibling temporary file and rename it onto the live
    path.
  • Rename the already-generated modified configuration onto the live path instead of copying over
    it, and tolerate the consumed temporary file during cleanup.
  • Make update_chassisdb_config write a sibling temporary file and publish it with
    os.replace().

How to verify it

Run concurrent JSON readers while repeatedly invoking the installed in-place writer and the
patched atomic writer against the same scratch configuration. Use identical writer iterations and
reader counts for both arms, and verify that the live database configuration remains untouched.

Which release branch to backport (provide reason below if selected)

  • 202305
  • 202311
  • 202405
  • 202411
  • 202505
  • 202511
  • 202512
  • 202605
  • 202608

Tracking issue/work item for backport/cherry-pick request (GitHub issue or Microsoft ADO):
N/A (internal tracking is not disclosed)

Failure type: other — existing non-atomic database configuration publication race

Tested branch

  • master
  • 202305
  • 202311
  • 202405
  • 202411
  • 202505
  • 202511
  • 202512
  • 202605
  • 202608
  • N/A

Test result

  • master: — HEAD was exercised in three patched boots as part
    of a broader startup-path test and produced zero parser errors. Because that arm contained
    additional startup-path changes, it is integration coverage rather than isolated proof for this
    PR. Restoring the control produced three errors.
  • 202605: — controlled A/B with 150 writes and four concurrent readers per arm:
    • Installed in-place writer: 118,554 successful reads and 701 empty reads.
    • Patched temp-file plus os.replace() writer: 132,972 successful reads and zero empty reads.
    • The experiment used a scratch copy; the live database configuration was not modified.

Description for the changelog

Publish database_config.json atomically to prevent readers from observing empty JSON during
normal updates.

The initial jinja render already publishes through a temp file and rename, but the
remaining publication sites still write the live path directly:

  - the copy from /etc/sonic/database_config*.json truncates the destination
  - the final copy of the modified config truncates it again
  - update_chassisdb_config reopens it with mode "w", which truncates before the
    new content is written

Readers therefore see an existing but empty file and log:

  ERR python3: :- parseDatabaseConfig: Sonic database config file syntax error >>
  [json.exception.parse_error.101] parse error at line 1, column 1: attempting to
  parse an empty input

The in-place rewrite kept the live file truncated for 285 us.
This window is independent of the platform slot queries: it also occurs on
platforms without chassisdb.conf, where the final copy is used instead.

Publish every site through a rename so a concurrent reader either sees the
previous content or the new content. The final publication renames the temp file
it already builds instead of copying it, so the cleanup that follows now tolerates
an already consumed temp file.

Signed-off-by: Charles Tsai <chartsai@nvidia.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@mssonicbld

Copy link
Copy Markdown
Collaborator

This PR has backport request for branch(es): 202605.
Added label(s) for branch(es) 202605.

---Powered by SONiC BuildBot

@mssonicbld mssonicbld added the Tested for 202605 branch Tested for 202605 branch label Sep 10, 2026
@mssonicbld

Copy link
Copy Markdown
Collaborator

The Tested branch section has been ticked and Test result is provided for branch(es): 202605. Added label(s): Tested for 202605 Branch.

---Powered by SONiC BuildBot

@chartsai-nvidia

Copy link
Copy Markdown
Contributor Author

/azpw retry

@mssonicbld

Copy link
Copy Markdown
Collaborator

Retrying failed(or canceled) jobs...

@mssonicbld

Copy link
Copy Markdown
Collaborator

Retrying failed(or canceled) stages in build 1217041:

✅Stage Test:

  • Job impacted-area-kvmtest-t0-vpp by Elastictest: retried.

@Sourabh-Kumar7

Copy link
Copy Markdown
Member

@qiluo-msft could you please help review this PR? thanks

@yxieca yxieca left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. Correct fix for the truncated-read race on database_config.json. Replacing in-place cp / open(...,"w") (which truncates the live file before streaming bytes) with temp-file + atomic rename (mv / os.replace) in all three write paths means concurrent readers — e.g. waitForAllInstanceDatabaseConfigJsonFilesReady — always see either the complete old file or the complete new one, never an empty/partial JSON.

The atomicity relies on rename(2) being atomic on the same filesystem, which holds here since the temp .json.new is created in the same directory as the destination. Extending the pattern already used in the rendered branch to the cp branch and update_chassisdb_config is consistent and closes the remaining gaps.

Minor (non-blocking): the temp name is a fixed .json.new rather than a PID/mktemp-suffixed name; fine here since the init path isn't run concurrently for the same file and the rename is still atomic.

@yxieca
yxieca merged commit 08dfcc7 into sonic-net:master Sep 22, 2026
30 checks passed
@mssonicbld

Copy link
Copy Markdown
Collaborator

Cherry-pick PR to 202605: #29693

@chartsai-nvidia
chartsai-nvidia deleted the chartsai/202605-parseDatabaseConfig branch September 23, 2026 16:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants