-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Process.Unix: handle ETXTBSY error when executing file that was just written by .NET. #59079
Conversation
…written by .NET. ETXTBSY means we're trying to execute a file that is open for write. This may be a file that was just written and closed, but is still referenced by another process that has forked but not yet exec-ed. When this error occurs, we wait for all processes to finish exec-ing, which causes the file to be closed (CLOEXEC). Then we start the process again.
Tagging subscribers to this area: @dotnet/area-system-diagnostics-process Issue DetailsETXTBSY means we're trying to execute a file that is open for write. When this error occurs, we wait for all processes to finish exec-ing, which causes the file to be closed (CLOEXEC). Then we start the process again. Fixes #58964. cc @agocke @jkotas @adamsitnik
|
This helps but it is not a 100% solution. We wait for all processes that have forked to exec-d. We consider it exec-ed when we've observed the close-on-exec of a pipe end that was handed to the child: runtime/src/libraries/Native/Unix/System.Native/pal_process.c Lines 452 to 456 in 4ac2aaa
So we know for sure the pipe end was closed, but this happens as part of a loop in the kernel and the handle we care about may come later in this loop... If in addition to the changes in this PR we do something that causes the handle to be closed between @agocke @jkotas @adamsitnik should we adopt the changes to |
Isn't this also only helping in the case where the process using the file was created by this parent process? It's using a lock specific to the process to achieve the waiting. Based on my current understanding, I don't think we should take this. It's introducing non-trivial additional complexity and synchronization and the fundamental issue still exists. |
Yes, this is for the specific use-case when a .NET application writes an executable file, and then executes it using A race occurs when another By taking the writer lock we wait until all processes have exec-ed and started to apply |
What happens if the file is written but the app neglects to close it... Process.Start will now hang rather than error? |
We handle |
Will the test you added succeed 100% of the time? |
No, I have to remove it. I'm ok if we won't merge because it is a niche use-case and not a 100% fix. I can add a test that ensures |
This is as good as I can make it. It's an improvement, but not a 100% solution. @stephentoub feel free to merge or close the PR. |
@stephentoub does this address your reservations above? |
My vote is for closing this PR. I do not think it is worth it given that it is not 100% fix. @tmds Thank you for giving it a shot! |
I very much appreciate the effort and the attempt, but my fundamental concern remains: it adds non-trivial complexity (introducing a retry loop, changing the synchronization scheme to employ an upgradeable read lock and taking the write lock in the middle to coordinate, etc.) and doesn't fully address the issue. |
I ended up adding a retry in the test loop, and that seems to have solved the problem there. Until Linux provides a more robust solution, I think users can address this on an individual basis |
ETXTBSY means we're trying to execute a file that is open for write.
This may be a file that was just written and closed, but is still referenced by another process that has forked but not yet exec-ed.
When this error occurs, we wait for all processes to finish exec-ing, which causes the file to be closed (CLOEXEC). Then we start the process again.
Fixes #58964.
cc @agocke @jkotas @adamsitnik