-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
os: RemoveAll does not always work on very large directories #20841
Comments
Note, using the system commands on windows and bash (WSL) work without issue. It's just in the |
For an example of the issue and status on Go itself see golang/go#20841 When working with large file sets such as those in a large dependency tree (e.g. thousands of files) functions such as os.RemoveAll and os.Rename can fail on Windows and Windows Subsystem for Linux. The system commands work without issue. This change detects Windows and the WSL environments then drops down to system commands to make these changes. On mac, linux, and other the os package functions are still used.
I tried running https://github.com/mattfarina/go-test-windows-files on my Windows XP and Windows 7. It works as expected - "go run main.go" prints "nil", and "files" directory is deleted. I tried running it couple of times, and it always succeeds. I tried both go1.8.3 and current tip. Alex |
@mattfarina, the question for Windows quirks is always: which virus scanner(s) are you using? |
@bradfitz great question. I used Windows 10 Pro Creators Edition to reproduce this. Some Glide users ran into a problem and this was the underlying cause. Windows Defender that came with the system by default is all I have for antivirus. The system has a minimal install. VSCode, git, go, and WSL are all that I installed to reproduce the issue. This may be a new issue to Windows 10 Creators Edition. I initially reproduced the Glide issue on the k8s/helm project. I'd previously worked on helm under Windows Anniversary using Glide without issue. Happy to supply other details that may help. |
What is the error message? Alex |
@alexbrainman See the example at https://github.com/mattfarina/go-test-windows-files. Readme has that detail for this case. |
Thank you. But the "remove files: directory not empty" message looks strange to me. Searching for "directory not empty" in Go repo, I find ENOTEMPTY. But I don't see how windows code in Go repo can return ENOTEMPTY. Can you try and see why your program returns "directory not empty" message? I am trying to understand which windows syscall fails and what error it returns. Thank you. Alex |
@alexbrainman just to clarify the error message, it's not
|
The "The directory is not empty" message must be ERROR_DIR_NOT_EMPTY. The only way you can get this message (as far as I know), if you are trying to delete directory with some files inside. Is it possible that some other program is creating files as you are running os.RemoveAll ? Something like:
If I run this program on my Windows PC, I get this:
Alex |
I'm facing this error through ... except maybe Windows Defender ... |
I can only give the not so helpful "works on my machine" response here, tested on W10(Ver:1703 Build:15063.447) with Go 1.8.3 and 1.9beta2. I have Windows defender disabled on this machine so maybe it's related. It might be worth running the tests with at least "Real-time protection" disabled since defender may have open handles when the files are fresh, although I'd imagine if this was the cause the results would be inconsistent. |
Check out: https://glennsarti.github.io/blog/wsl-ruby-puppet/ For some instructions about disabling Defender on WSL files, it would be interesting to see if that fixes things on the WSL side... |
I don't repro on Windows10. I use Windows Defender. |
@brendandburns I just tried testing with the exclusion added and still get the issue. Both with the test repo from @mattfarina and trying it with glide. Let me know if I can test something else |
I also just tried turning off real-time protection to no avail |
@kumarharsh and @thomastaylor312 if you can reproduce what @mattfarina described (the https://github.com/mattfarina/go-test-windows-files ), then you should be able to work out what is going on with os.RemoteAll. For example, does this program https://github.com/mattfarina/go-test-windows-files/blob/master/main.go fails? What is the error message? Can you see any files remain in the "files" directory after program completes? Why did the program skipped them while deleting others? Did the program even attempted to delete them? Were the files in the "files" folder before you run the program? I would be interested in every error that occurs inside of os.RemoveAll, so I would be adding println everywhere to print every error. What are these errors? Can you see any errors related to the files that are left in the "files" directory. Alex |
@alexbrainman I will keep debugging it. But here are the answers to your questions: I'll add some more debugging and see what I can find out |
Is the error message "directory not empty" or "The directory is not empty"?
There are 10001 files in that directory. So you are left with about 4901 remaining files. Out of remaining 4901 files, did os.RemoveAll even attempted to delete them? You can put println before each file is removed and log println output into a file, and than look in that file. If you discover that os.RemoveAll did attempt to delete them all, then each file deletion must have failed. What are the error messages for each failure? Again you could print them all with println. Thank you. Alex |
@alexbrainman That is what I meant by "debugging" in this case. 🙂 I am planning on sprinkling As for the error message, I copy pasted it directly from the output. It is |
In the case the error In my case the example at https://github.com/mattfarina/go-test-windows-files removes a different number of files on each run. The last two runs removed 5118 and 5101 files. I plan to merge in some changes to Glide this week to fix this. Hopefully it's just a temporary work around until we have a better fix. @brendandburns Thanks for the Ruby WSL link. I'll dig into that a little more. |
Ok, getting a little further on this. The |
Sweet!
…On Sep 23, 2017 18:24, "Brad Fitzpatrick" ***@***.***> wrote:
/cc @jessfraz <https://github.com/jessfraz> for WSL problem.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#20841 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABYNbNmO3WnGnC0vmVvz8cVcoq7LdKvpks5slYU3gaJpZM4OIstj>
.
|
I think the fix is in https://golang.org/cl/62970 . |
@zhengtg you are correct, CustomRename function has a bug (I can reproduce it here - Windows move command refuses to move directory if source and destination are on different volumes), but CustomRename function is part of glide project, and you should use https://github.com/Masterminds/glide/issues to report problems with glide command. Alex |
Sorry, deleted my comment because it was totally wrong. |
For go1.10beta1, I confirmed this patch fixed the problem for my environment at least. Environment
|
@tyru correct, there is no fix for this yet, in any branch, and it will probably not be fixed in either Go 1.9.x or Go 1.10.x. It's really Microsoft's job to fix this in WSL if they want to fully act like Linux. But we might consider a fix for Go 1.11. The change above (https://golang.org/cl/62970) has merge conflicts and unaddressed feedback. Ping @raggi. :) |
ping @jstarks |
Interesting. We (WSL team) will look into this. |
OK, that was fast. We believe this has been fixed in WSL in the recently released Windows 10 Fall Creators Update ("RS3", build 16299). Please let us know if you're able to reproduce this after updating to the latest Windows release. |
Sorry, catching up with the comments on the original CL has been falling down my priority list. I won't be picking it up until January at the earliest. It's important to point out here that the title is misleading and makes me sad that I mentioned Windows in the original bug report, because it's too easy to focus on that too much. This behavior exists for many filesystems on many platforms. The spec allows for concurrent modification and for unbounded directory sizes. There is no tractable implementation for very large directories other than the behavior the original CL aims to fix. Platform doesn't really matter. You can almost certainly replicate the original bug with sufficiently large directories on both OSX and NFS today. |
@raggi, thanks for reminding us of that. I remember you did mention that in the CL review comments. Will retitle. |
I also encounter this error when using
Is there any good way to replace |
@cwen0 please file a new issue. If it turns out it’s a duplicate we’ll link the two issues. |
ok, Thanks |
Change https://golang.org/cl/121255 mentions this issue: |
Change https://golang.org/cl/171099 mentions this issue: |
os.RemoveAll
and other os operations (e.g.,os.Rename
) fail with large sets of files on Windows.Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?1.8.3
What operating system and processor architecture are you using (
go env
)?Windows amd64 and Windows Subsystem for Linux amd64
What did you do?
An example repo can be found at https://github.com/mattfarina/go-test-windows-files. It's a repo with 10,000 files to be deleted to use as an example.
What did you expect to see?
I expect
os.RemoveAll
to delete all the filesWhat did you see instead?
Some of the files are deleted and then an error is thrown.
The text was updated successfully, but these errors were encountered: