-
Notifications
You must be signed in to change notification settings - Fork 39.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use Lstat in plugin watcher to avoid Windows problem #99463
Conversation
User Lstat in plugin watcher due to Windows issue Change-Id: I4f9b808829f1a56dc622e343c291d3ffc316f416
@jingxu97: This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the The Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/lgtm |
/retest |
Is that desired behavior? |
@jingxu97 could you describe or add more context about what this PR is fixing? Thanks. |
I added more context in the commit. I have seen issues mentioned for Stat() in Windows like golang/go#34900 But they are not the exact behavior I am seeing here. |
Here Lstat is used for checking whether the file is a dir or not. If it is not a dir, it will further check whether it is a domain socket (windows and Linux use different ways to check it due to issue in Windows here golang/go#33357) In this aspect, I think it is safe to use Lstat first to check whether it is a dir or not. A symlink is not considered a dir, then it will future to check whether it is a socket or not (in Linux, it will then use os.Stat() to check it). |
We ran into this with the device manager: #97576 |
/test pull-kubernetes-e2e-aks-engine-azure-windows |
/lgtm |
/retest |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jingxu97, yujuhong The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@jingxu97: The following tests failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
/retest |
Please make sure to add a release note to this PR. User visible change is that symlinks inside plugin directory for CSI and device plugins will no longer be followed. |
I think no matter with or without this change, if the socket file is a symlink, for Linux, it will follow it. There are two checks for Linux,
Actually with or without this change, the behavior of the code will not change. For linux, it uses os.Stat() twice
Before fix, if path is a symlink, and target path is a dir, then the code will return immediately
So the first os.Stat (now it changed to os.Lstat()) should not affect the final result. Actually the first check is not very necessary in my option since the actual check of domain socket is in the second check. |
@marosset Now we can confirm this os.Stat() is introduced in the new 20H2 Windows image. The older ones are fine. Could you share the link for opening Windows issue? Thanks! |
Thanks! I opened an issue there microsoft/Windows-Containers#97 |
@@ -159,7 +159,7 @@ func (w *Watcher) traversePluginDir(dir string) error { | |||
func (w *Watcher) handleCreateEvent(event fsnotify.Event) error { | |||
klog.V(6).Infof("Handling create event: %v", event) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this breaks plugins that register in the following way:
plugin sets up a dir on disk somewhere:
/myplugin/mysocket.sock
then symlinks its dir into the kubelet's plugin dir:
/var/plugindir/myplugin -> /myplugin
event.Name
would be /var/plugindir/myplugin
previously:
os.Stat
would follow, and get info for /var/plugindir/myplugin- fi.IsDir() would be true
- we would traverse and find the plugin socket on line 185
with this change:
os.Lstat
does not followfi.IsDir()
is falseIsUnixDomainSocket
is also false- we ignore and return "klog.V(5).Infof("Ignoring non socket file %s", fi.Name())"
If os.Stat has known issues with sockets on windows, I think this would be a better workaround:
fi, err := os.Stat(event.Name)
if err != nil && os.GOOS == "windows" {
fi, err = os.Lstat(event.Name)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
created a PR to address #99723
I missed the traverse part. Thank you for pointing it out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested this logic on Windows and found out in the case path is a symlink points to a dir, os.Stat() will not work for all Windows versions tested including LSTC and SAC
The error is "Access is Denied".
So this use case will not work for Windows before or after this change.
This PR tries to use Lstat in plugin watcher due to Windows issue of using os.Stat(). In some Windows tests with SAC 1909 Windows version, we notice that os.Stat() return error for domain socket in Windows.
\var\lib\kubelet\plugins_registry\pd.csi.storage.gke.io-reg.sock: The file cannot be accessed by the system.
But this behavior is not consistent, though.
Change-Id: I4f9b808829f1a56dc622e343c291d3ffc316f416
What type of PR is this?
What this PR does / why we need it:
Which issue(s) this PR fixes:
Fixes #
Special notes for your reviewer:
Does this PR introduce a user-facing change?
Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.: