-
Notifications
You must be signed in to change notification settings - Fork 67
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
Allow Walk to visit volume mounts on Windows #208
Allow Walk to visit volume mounts on Windows #208
Conversation
c085bb9
to
9c603e2
Compare
5ad02bc
to
8e28ee2
Compare
A sample application to test this: package main
import (
"errors"
"flag"
"fmt"
"log"
"os"
"path/filepath"
"syscall"
"github.com/containerd/continuity/pathdriver"
"golang.org/x/sys/windows"
)
func isSystemOrHidden(path string) (bool, error) {
attr, err := windows.GetFileAttributes(syscall.StringToUTF16Ptr(path))
if err != nil {
return false, err
}
if attr&syscall.FILE_ATTRIBUTE_HIDDEN != 0 && attr&syscall.FILE_ATTRIBUTE_SYSTEM != 0 {
return true, nil
}
return false, nil
}
func main() {
pth := flag.String("target", "", "path to walk")
flag.Parse()
final, err := filepath.Abs(*pth)
if err != nil {
log.Fatal(err)
}
fmt.Println(final)
err = pathdriver.LocalPathDriver.Walk(*pth, func(path string, info os.FileInfo, err error) error {
if err != nil {
isSystemOrHidden, errHidden := isSystemOrHidden(path)
if errHidden != nil {
return errHidden
}
if isSystemOrHidden {
log.Printf("Skipping hidden system file/folder: %s", path)
return nil
}
if errors.Is(err, pathdriver.ErrPathRecursion) {
log.Printf("Not visiting previously seen path %s", path)
return nil
}
log.Fatalf("%+v", err)
}
fmt.Printf("visiting %v\n", path)
return nil
})
if err != nil {
log.Fatalf("error: %+v", err)
}
} The folder structure and volume mount set up for testing. Volume is mounted twice. Once in Output of that sample app: |
I had written some tests that create and mount VHDs, but they end up pulling in hcsshim... (for access to It's possible that hcsshim has been fixed to not end up pulling in containerd when used as a library (it was only needed in the test code) but I realise now I had forgotten about that PR for more than a year. >_< |
f9ea6aa
to
a960fd0
Compare
pathdriver/path_driver_nix.go
Outdated
@@ -0,0 +1,29 @@ | |||
//go:build !windows |
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 should be path_driver_unix.go
.
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 renamed the file.
This change adds a fork of the filepath.Walk function from the standard library, with changes that allows it to visit reparse points that are in fact volume mounts. Currently go makes no distinction between a symlink, directory junction, volume mount or Unix domain socket. All reparse points are regarded as symlinks. This means that FileMode does not have ModeDir set for any path that also has ModeSymlink. This includes volume mounts. See: https://go-review.googlesource.com/c/go/+/41830/ This implementation also attempts to avoid recursions. Fixes: containerd#174 Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
a960fd0
to
b547877
Compare
} | ||
|
||
func testWalk(t *testing.T, walk func(string, fs.WalkDirFunc) error, errVisit int) { | ||
if runtime.GOOS == "ios" { |
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.
Isn't it for Windows?
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.
The current test is a copy of the test from the standard library. I am looking into adding an additional test to check the volume mount specific code and recursion prevention, but that requires mounting a volume somewhere and attempting to walk it. I am unsure how this scenario would easily be set up. Locally, I created a VHDx, attached it to the system, created a partition, formatted it and then mounted it. But this requires some powershell commandlets to be available, or at least the windows provider to handle VHDx disks.
It is. The tests are copied from the standard library. The idea was to make sure we maintain compatibility. But this PR was useful when we thought we needed to walk junctions (windows symlinks). Since then, we've replaced junctions with the bind filter, so this is no longer needed.
Closing this PR. We've replaced the need for junctions with the bind filter (containerd/containerd#8043 (comment)), which does not use reparse points. If anyone still needs this work, feel free to grab the branch and open a new PR. |
This change adds a fork of the filepath.Walk function from the standard library, with changes that allows it to visit reparse points that are in fact volume mounts.
Currently go makes no distinction between a symlink, directory junction, volume mount or Unix domain socket. All reparse points are regarded as symlinks. This means that FileMode does not have ModeDir set for any path that also has ModeSymlink. This includes volume mounts. See: https://go-review.googlesource.com/c/go/+/41830/
This implementation also attempts to avoid recursions. I am on the fence about the added
ErrPathRecursion
. The idea is to raise an error if a recursion is detected and allow thewalkFn
function to handle that specific error. But I am not sure what the idiomatic way to handle this, is. Any suggestions are welcome.The current test is a copy of the test from the standard library. I am looking into adding an additional test to check the volume mount specific code and recursion prevention, but that requires mounting a volume somewhere and attempting to walk it. I am unsure how this scenario would easily be set up. Locally, I created a VHDx, attached it to the system, created a partition, formatted it and then mounted it. But this requires some powershell commandlets to be available, or at least the windows provider to handle VHDx disks.
This change should remove the need to resort to workarounds like these: containerd/containerd@100624b on Windows. See containerd/containerd#4419 for details regarding the need for this.
Signed-off-by: Gabriel Adrian Samfira gsamfira@cloudbasesolutions.com