-
Notifications
You must be signed in to change notification settings - Fork 594
fix(snapshots): Append path separator to Shadow Copy root directory on Windows #3891
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
Conversation
|
Something additional to note, there is a similar check going on here in the NewEntry function: kopia/fs/localfs/local_fs_os.go Lines 112 to 128 in fcb8197
I wonder if it would be useful to change this to use the new |
|
I applied this PR on top of v0.17.0 tag which I confirmed to be showing the problem reported in #3842 using However, it's worth noting that appending a trailing backslash when detecting the |
|
Thanks for the extra info.
I wonder if there's any Windows API to detect or resolve links like this in the Object namespace? For normal symlinks / reparse points in the filesystem this can be done with os.Lstat, but as noted in the code in my second comment, Lstat seems to fail on these kinds of paths unless you "manually" resolve them with the trailing backslash. If there's a way to detect them directly, it might make sense to implement them like normal symlinks are now, and there wouldn't be any need to handle shadow volumes explicitly.
I considered doing something like this but I was worried about edge cases, which is why I went out of my way to make sure the workaround is only applied to the top-level root directory. Since "inside" the shadow volume device is just a normal filesystem, appending a backslash anywhere after the root might have different consequences, like resolving links. If we did something more generic, it would definitely need a lot more testing to make sure all the edge cases are handled correctly. |
|
I ended up reading a lot about Windows path handling, this article seems to contain a lot of the relevant information. I believe the fundamental issue here is that Windows treats opening the path Unfortunately, it seems non-triviable to handle this "correctly". It seems impossible to know whether a UNC path points to a device object without doing multiple Windows-specific syscalls for every path. That being said, I think there is a way to handle this a bit more cleanly. For one, rather than the current func (e *filesystemEntry) isWindowsVSSVolume() bool {
return runtime.GOOS == "windows" &&
e.prefix == `\\?\GLOBALROOT\Device\` &&
strings.HasPrefix(e.Name(), "HarddiskVolumeShadowCopy")
}then we can just do this in fullPath := fsd.fullPath()
appendPath := ""
if fsd.isWindowsVSSVolume() {
appendPath = string(os.PathSeparator)
}
f, direrr := os.Open(fullPath + appendPath) //nolint:gosecand that's all the logic needed. If we ever want to make it a bit more generic in the future. the If there's no objections to this revised patch, I think I'll push another commit with it in a little bit since it's pretty much the same logic as the previous commit, just cleaner. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3891 +/- ##
==========================================
+ Coverage 75.86% 76.38% +0.51%
==========================================
Files 470 530 +60
Lines 37301 40476 +3175
==========================================
+ Hits 28299 30917 +2618
- Misses 7071 7511 +440
- Partials 1931 2048 +117 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Regarding the test coverage, should I add a test that covers this case? I think I could just mostly copy https://github.com/kopia/kopia/blob/master/tests/os_snapshot_test/os_snapshot_windows_test.go but enable |
|
Tested on Windows 10 with a boot drive SSD and a data HDD, working just fine. Thank you for your contribution, I hope to see this upstream soon :) |
|
I just tested this on the latest release of Windows 11 (24H2) and it's working as expected. |
|
Now that we finally have a new Kopia release is there any chance this fix could get some love? |
|
Upgraded from 0.16 to 0.18.2 and vss broke, applied this path, now it works, not much more to say. |
|
Are there any specific issues blocking this from getting merged? This is the thing blocking me from upgrading off of 0.16. It'd be great to know if there is anything to help move this forward. |
Looks like it's (at least) awaiting a review. I built my own 18.2 with this change included, was hoping it would make 19! |
|
Also waiting for this fix, as it's a blocking usecase for me. |
|
@julio-lopez or @jkowalski would it be possible get this merged? Are there any blockers preventing this from going through? |
+1, was not able to make a local working build with this, but user report it's working. |
|
I was hoping the silence on this thread meant this wasn't a problem any more in .21 but it looks like it still is. Fortunately the changes in this PR still work if you're able to build for yourself. |
|
Had the same hope that the fix will be merged at least into this release. I understand that Windows is not top priority, but this bug makes it nearly unuseable for windows clients. Using 0.16 is a workaround, but not for such long time Pushing again so we maybe have it for 0.22 then :-) |
|
i'll get this merged, i got a hold of a Windows box and will try it out and merge after that. |
|
ok, i think it works, i'm going to merge, please try it for your use case when a build is produced |
Thanks for your effort in this case. Tested recent master build 20250803.0.35640 installed via. KopiaUI-Setup-20250803.0.35640.exe. Confirmed working. |
Additional cleanups: - make fs/localfs.isWindows a const - move Windows-specific functionality to local_fs_windows.go - cleanup: remove //nolint:revive annotations Ref: - Followup to #3891
This is a fix for #3842.
It's a slightly modified version of the patch in #3842 (comment), I separated the code out into a
maybefunction and added some tests.The root cause of this issue seems to be a regression in Go 1.22 (see #3842 (comment)), but as discussed with jkowalski in the issue, it seems better to just fix this up with a special case in Kopia.