Skip to content

fix: handle dangling symlink in config-manager updateSymlink - #1982

Merged
abrarshivani merged 1 commit into
NVIDIA:mainfrom
yoonhyunwoo:fix/issue-364-config-manager-symlink
Aug 29, 2026
Merged

fix: handle dangling symlink in config-manager updateSymlink#1982
abrarshivani merged 1 commit into
NVIDIA:mainfrom
yoonhyunwoo:fix/issue-364-config-manager-symlink

Conversation

@yoonhyunwoo

@yoonhyunwoo yoonhyunwoo commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fixes #364
Follow-up to #365

dangling symlink is misjudged as "missing" and recreation fails.
os.Readlink checks the symlink itself, so it works correctly even when dangling.

@copy-pr-bot

copy-pr-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@yoonhyunwoo

Copy link
Copy Markdown
Contributor Author

For context: we hit this in production. After a ConfigMap update, the config-manager sidecar of gpu-feature-discovery / nvidia-device-plugin-mps-control-daemon pods got stuck in CrashLoopBackOff, repeatedly logging:

Error: error creating symlink: symlink /available-configs/<config> /config/config.yaml: file exists

Retrying never recovers because the dangling symlink itself persists across restarts, so the pod needs manual intervention (delete the symlink or recreate the pod).

@abrarshivani

Copy link
Copy Markdown
Contributor

Thanks @yoonhyunwoo for fixing this. LGTM. Can we also add a regression test covering the dangling-symlink case?

@abrarshivani

Copy link
Copy Markdown
Contributor

/ok to test f2f059f

@abrarshivani

Copy link
Copy Markdown
Contributor

@yoonhyunwoo Thanks for adding the tests. Can you please rebase the branch on the latest main, squash the commits, and make sure the resulting commit has a verified signature: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits

Signed-off-by: yoonhyunwoo <yjs88zerg@gmail.com>
@yoonhyunwoo
yoonhyunwoo force-pushed the fix/issue-364-config-manager-symlink branch from f2f059f to 1a69452 Compare August 28, 2026 02:09
@yoonhyunwoo

Copy link
Copy Markdown
Contributor Author

@yoonhyunwoo Thanks for adding the tests. Can you please rebase the branch on the latest main, squash the commits, and make sure the resulting commit has a verified signature: docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits

Done!

@abrarshivani

Copy link
Copy Markdown
Contributor

/ok to test 1a69452

@abrarshivani
abrarshivani enabled auto-merge August 28, 2026 22:50
@abrarshivani
abrarshivani merged commit 5a3b3d8 into NVIDIA:main Aug 29, 2026
12 checks passed
return false, nil
}
} else if !os.IsNotExist(err) && !errors.Is(err, syscall.EINVAL) {
return false, fmt.Errorf("error reading symlink '%s': %v", f.ConfigFileDst, err)

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.

If you want to quote strings it's better to use %q instead of %s. In this case however, it's better to just unquote the string as the logs are emitted in JSON format.

Suggested change
return false, fmt.Errorf("error reading symlink '%s': %v", f.ConfigFileDst, err)
return false, fmt.Errorf("error reading symlink %s: %w", f.ConfigFileDst, err)

}
err = os.Remove(f.ConfigFileDst)
if err != nil && !os.IsNotExist(err) {
return false, fmt.Errorf("error removing existing config: %v", err)

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.

Suggested change
return false, fmt.Errorf("error removing existing config: %v", err)
return false, fmt.Errorf("error removing existing config: %w", err)

return false, fmt.Errorf("error removing existing config: %v", err)
}
err = os.Remove(f.ConfigFileDst)
if err != nil && !os.IsNotExist(err) {

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.

Isn't this redundant?

!os.IsNotExist(err)

We already check for an IsNotExist error earlier.

config: "missing-config",
wantChanged: true,
},
{

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.

This test is not clear to me. It seems like it depends on the previous test. If this is indeed the case, then it's an antipattern. The unit test should be independent of any other unit tests and it should pass when run in isolation.

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.

Time-slicing config update: "Error: error creating symlink: file exists"

3 participants