Skip to content

Cache parsed configuration files to avoid redundant reads on startup (#59807)#69779

Open
ggiesen wants to merge 1 commit into
saltstack:3006.xfrom
ggiesen:fix-59807-config-cache
Open

Cache parsed configuration files to avoid redundant reads on startup (#59807)#69779
ggiesen wants to merge 1 commit into
saltstack:3006.xfrom
ggiesen:fix-59807-config-cache

Conversation

@ggiesen

@ggiesen ggiesen commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Caches parsed configuration files so a given file is read and parsed from disk once while it is unchanged, instead of on every master_config/minion_config/client_config call.

What issues does this PR fix or reference?

Fixes #59807

Previous Behavior

salt.config._read_conf_file re-read and re-parsed the configuration file from disk on every call. During daemon startup the same file is loaded many times: each MasterMinion and LocalClient built by _load_modules, across every forked subprocess (Maintenance, MWorkers, ReqServer, ...), calls back through master_config/minion_config -> load_config -> _read_conf_file. Measured on 3006 with a trivial master config, the file was openat()ed 84 times during startup (across 8 processes); the reporter saw 646 with a gitfs/ext_pillar config.

New Behavior

_read_conf_file caches the parsed result keyed by the file's (st_mtime_ns, st_size) and returns a deep copy to each caller. Unchanged files are served from the cache; a changed file (for example a reload) has a different mtime or size and is re-read. The deep copy means callers that mutate the returned opts cannot corrupt the cached copy. With this change the same trivial-config startup reads the file once (84 -> 1), and the master boots and generates its keys normally.

Verified:

  • openat() count for the config file drops from 84 to 1 across a full salt-master startup (strace).
  • Returned opts match the file contents; repeated calls return equal but distinct objects; mutating one does not affect the next.
  • A file changed on disk is re-read (new size/mtime).
  • tests/unit/test_config.py still passes (76 passed, 7 skipped); new tests added.

Merge requirements satisfied?

  • Docs - n/a
  • Changelog - changelog/59807.fixed.md
  • Tests written/updated - tests/pytests/unit/config/test_conf_file_cache.py (the parse-once test fails without this change)

Commits signed with GPG?

No

Every master_config/minion_config/client_config call re-read and re-parsed the
configuration file from disk. During master startup this happens many times per
process across all forked subprocesses -- a trivial config was read 84 times,
and configs with gitfs/ext_pillar remotes far more (the reporter saw 646).

Cache the parsed result in _read_conf_file, keyed by the file's mtime and size,
and hand callers a deep copy so they cannot corrupt the cache. A changed file
(reload) is re-read. This reduces the trivial-config startup read count from 84
to 1.

Fixes saltstack#59807
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant