[release/1.4] windows: Use GetFinalPathNameByHandle for ResolveSymbolicLink#1636
[release/1.4] windows: Use GetFinalPathNameByHandle for ResolveSymbolicLink#1636fuweid merged 2 commits intocontainerd:release/1.4from
Conversation
|
The CI failures look unrelated. Maybe just hitting rate limits on gcr.io? I think it's safe to ignore them. |
|
@mikebrow looks like |
|
@mikebrow any thoughts on what is needed here to help CI? |
thx almost forgot about this repo :-) Let's merge this: #1638 brings critest back on-line then you can rebase.. |
|
kk you should be ok for critest.. after rebase on |
|
FYI also updated vendor, and cleaned up the node e2e test over here ... #1639 green lights! |
|
@kevpar need rebase here~ |
Updating with new versions needed to support using GetFinalPathNameByHandle. Signed-off-by: Kevin Parsons <kevpar@microsoft.com>
|
@mikebrow thank you! I've rebased now. |
|
@mikebrow de-nit'd :) |
| // We could use os.Open if the path is a file, but it's easier to just use the same code for both. | ||
| // Therefore, we call windows.CreateFile directly. | ||
| func openPath(path string) (windows.Handle, error) { | ||
| u16, err := windows.UTF16PtrFromString(path) |
There was a problem hiding this comment.
Is it possible to use syscall.UTF16PtrFromString? I see stdlib provides the function. https://golang.org/pkg/syscall/?GOOS=windows#UTF16PtrFromString.
GetFinalPathNameByHandle is unavailable in stdlib syscall.
| New: func() interface{} { | ||
| // Size of buffer chosen somewhat arbitrarily to accommodate a large number of path strings. | ||
| // MAX_PATH (260) + size of volume GUID prefix (49) + null terminator = 310. | ||
| b := make([]uint16, 310) |
There was a problem hiding this comment.
Suggest to add docs here https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd.
Starting in Windows 10, version 1607, MAX_PATH limitations have been removed from common Win32 file and directory functions.
There was a problem hiding this comment.
Given this is a backport (of containerd/containerd@b0d3b35), my assumption is we shouldn't diverge from what was put into containerd master. For this and the other comments you have left, do you feel these should be addressed here?
There was a problem hiding this comment.
I am fine with current change ~ just think 4096 looks better than 310
| // correct size for the call. | ||
| func getFinalPathNameByHandle(h windows.Handle, flags uint32) (string, error) { | ||
| b := *(pool.Get().(*[]uint16)) | ||
| defer func() { pool.Put(&b) }() |
There was a problem hiding this comment.
The b has been re-allocated. defer should be handled in some condition.
--> in for loop
// If the buffer wasn't large enough, n will be the total size needed (including null terminator).
// Resize and try again.
if n > uint32(len(b) {
b = make([]uint16, n)
continue
}There was a problem hiding this comment.
I'm not sure I understand your comment. Can you clarify what you're asking for?
There was a problem hiding this comment.
Sorry for the late reply. A b is from pool.Get so that we should put the b back into the pool.
But the b has been changed when the size of original b is not large enough. In this case, it is not good to put the changed b into the pool.
This change splits the definition of pkg/cri/os.ResolveSymbolicLink by platform (windows/!windows), and switches to an alternate implementation for Windows. This aims to fix the issue described in containerd/containerd#5405. The previous implementation which just called filepath.EvalSymlinks has historically had issues on Windows. One of these issues we were able to fix in Go, but EvalSymlinks's behavior is not well specified on Windows, and there could easily be more issues in the future, so it seems prudent to move to a separate implementation for Windows. The new implementation uses the Windows GetFinalPathNameByHandle API, which takes a handle to an open file or directory and some flags, and returns the "real" name for the object. See comments in the code for details on the implementation. I have tested this change with a variety of mounts and everything seems to work as expected. Functions that make incorrect assumptions on what a Windows path can look like may have some trouble with the \\?\ path syntax. For instance EvalSymlinks fails when given a \\?\UNC\ path. For this reason, the resolvePath implementation modifies the returned path to translate to the more common form (\\?\UNC\server\share -> \\server\share). Signed-off-by: Kevin Parsons <kevpar@microsoft.com> From containerd/containerd@b0d3b35
|
/test pull-cri-containerd-node-e2e |
|
Thanks @fuweid! |
Backport of containerd/containerd#5411 for
release/1.4. I also had to update some vendoring to bring in the right dependencies.This change splits the definition of pkg/cri/os.ResolveSymbolicLink by
platform (windows/!windows), and switches to an alternate implementation
for Windows. This aims to fix the issue described in containerd/containerd#5405.
The previous implementation which just called filepath.EvalSymlinks has
historically had issues on Windows. One of these issues we were able to
fix in Go, but EvalSymlinks's behavior is not well specified on
Windows, and there could easily be more issues in the future, so it
seems prudent to move to a separate implementation for Windows.
The new implementation uses the Windows GetFinalPathNameByHandle API,
which takes a handle to an open file or directory and some flags, and
returns the "real" name for the object. See comments in the code for
details on the implementation.
I have tested this change with a variety of mounts and everything seems
to work as expected. Functions that make incorrect assumptions on what a
Windows path can look like may have some trouble with the \?\ path
syntax. For instance EvalSymlinks fails when given a \?\UNC\ path. For
this reason, the resolvePath implementation modifies the returned path
to translate to the more common form (\?\UNC\server\share ->
\server\share).
Signed-off-by: Kevin Parsons kevpar@microsoft.com
From containerd/containerd@b0d3b35