cargo add: "failed to persist temporary file: Text file busy" on vboxsf (Linux guest Windows host)
Problem
When the cargo project directory is in vboxsf file system (VirtualBox shared folder) that is shared from host Windows system to guest Linux, then the cargo add <crate> command fails with the error:
error: failed to persist temporary file: Text file busy (os error 26)
I noticed this after upgrading to rust 1.76.0, but the regression may have been there in 1.75.0 too. The cargo add was working in older versions inside a vboxsf shared directory.
Steps
- In VirtualBox Linux guest system, go to a cargo project inside a vboxsf shared directory from Windows host system.
- Execute cargo add command.
- The error is printed, the
Cargo.tomlfile is not updated, and a temporary file (e.g.Cargo.tomln1aoHw) is left into directory.
Possible Solution(s)
The regression is probably caused by the change #12744, which introduces write_atomic function that uses the tempfile crate. The tempfile crate assumes "unix semantics", that files can be unlinked and renamed while holding a file descriptor to them. However, in the case of vboxsf filesystem shared from Windows, the files cannot be either renamed or unlinked while having an open file descriptor to them.
Debugging with strace shows that the rename and unlink calls are done between open and close:
openat(AT_FDCWD, "/media/vboxsf/.../Cargo.tomleN6hA9", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0600) = 3
write(3, "[package]\nname = "..., 241) = 241
renameat(AT_FDCWD, "/media/vboxsf/.../Cargo.tomleN6hA9", AT_FDCWD, "/media/vboxsf/.../Cargo.toml") = -1 ETXTBSY (Text file busy)
...
write(2, " Text file busy (os error 26)\n", 31) = 31
unlink("/media/vboxsf/.../Cargo.tomleN6hA9") = -1 ETXTBSY (Text file busy)
close(3) = 0
Notes
No response
Version
cargo 1.76.0 (c84b36747 2024-01-18)
release: 1.76.0
commit-hash: c84b367471a2db61d2c2c6aab605b14130b8a31b
commit-date: 2024-01-18
host: x86_64-unknown-linux-gnu
libgit2: 1.7.1 (sys:0.18.1 vendored)
libcurl: 8.5.0-DEV (sys:0.4.70+curl-8.5.0 vendored ssl:OpenSSL/1.1.1w)
ssl: OpenSSL 1.1.1w 11 Sep 2023
os: Debian 12 (bookworm) [64-bit]
Thank you for writing down such a detailed report!
By reading your trace it's very likely #12744 is the root cuase, though I currently don't have either Virtualbox or Windows at hand to verify. Could you help us bisect if #12744 is really the culprit?
If it is, it might be great to file an issue against tempfile and fix the bug there :)
Rust 1.82 is unable to build any project because of errors like this:
error: failed to build archive at `/home/user/Projects/diswall-rs/target/x86_64-unknown-linux-musl/release/deps/libcfg_if-62283c796ab26270.rlib`: failed to rename archive file: Text file busy (os error 26)
error: could not compile `cfg-if` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: failed to build archive at `/home/user/Projects/diswall-rs/target/x86_64-unknown-linux-musl/release/deps/libsubtle-04f6486aeb772fc9.rlib`: failed to rename archive file: Text file busy (os error 26)
error: could not compile `subtle` (lib) due to 1 previous error
error: failed to build archive at `/home/user/Projects/diswall-rs/target/release/deps/libunicode_ident-c69e4dea3672fd8c.rlib`: failed to rename archive file: Text file busy (os error 26)
error: could not compile `unicode-ident` (lib) due to 1 previous error
error: failed to build archive at `/home/user/Projects/diswall-rs/target/x86_64-unknown-linux-musl/release/deps/libzeroize-6a886cbe68da3e09.rlib`: failed to rename archive file: Text file busy (os error 26)
error: could not compile `zeroize` (lib) due to 1 previous error
error: failed to build archive at `/home/user/Projects/diswall-rs/target/x86_64-unknown-linux-musl/release/deps/liblog-23e5e3c6846e7920.rlib`: failed to rename archive file: Text file busy (os error 26)
error: failed to build archive at `/home/user/Projects/diswall-rs/target/release/deps/libshlex-68be365723bcd025.rlib`: failed to rename archive file: Text file busy (os error 26)
error: could not compile `log` (lib) due to 1 previous error
error: failed to build archive at `/home/user/Projects/diswall-rs/target/x86_64-unknown-linux-musl/release/deps/libbyteorder-e576a0bc308acc2d.rlib`: failed to rename archive file: Text file busy (os error 26)
error: could not compile `shlex` (lib) due to 1 previous error
error: could not compile `byteorder` (lib) due to 1 previous error
error: failed to build archive at `/home/user/Projects/diswall-rs/target/release/deps/libversion_check-7c73565ad9bd4316.rlib`: failed to rename archive file: Text file busy (os error 26)
error: could not compile `version_check` (lib) due to 1 previous error
error: failed to build archive at `/home/user/Projects/diswall-rs/target/x86_64-unknown-linux-musl/release/deps/librustls_pki_types-1a41b8441c75bb91.rlib`: failed to rename archive file: Text file busy (os error 26)
error: could not compile `rustls-pki-types` (lib) due to 1 previous error
error: failed to build archive at `/home/user/Projects/diswall-rs/target/release/deps/libautocfg-456e6ccf713ad1c2.rlib`: failed to rename archive file: Text file busy (os error 26)
error: could not compile `autocfg` (lib) due to 1 previous error
But if I switch to 1.80.1, it builds without errors.
@Revertron
Could you provide more information of what platform and version you're in? Also does it not work with 1.81 either?
@weihanglo It is broken for debug builds very long ago (didn't use them). But release builds are broken in some recent version. I'm trying to find which nightly was first. But I'll give you results tomorrow.
Debug build is broken like this:
info: override toolchain for '/home/user/Projects/dlh' set to 'nightly-2023-11-27-x86_64-unknown-linux-gnu'
Compiling dlh v0.1.0 (/home/user/Projects/dlh)
error: failed to move dependency graph from `/home/user/Projects/dlh/target/debug/incremental/dlh-2gokpr925ws16/s-h1a7uyxfl1-15w1pl3-working/dep-graph.part.bin` to `/home/user/Projects/dlh/target/debug/incremental/dlh-2gokpr925ws16/s-h1a7uyxfl1-15w1pl3-working/dep-graph.bin`: Text file busy (os error 26)
And release version is broken like this:
info: override toolchain for '/home/user/Projects/diswall-rs' set to 'nightly-2024-05-20-x86_64-unknown-linux-gnu'
Compiling proc-macro2 v1.0.88
... snip ...
Compiling smallvec v1.13.2
error: couldn't read /home/user/Projects/diswall-rs/target/release/build/rustversion-67b4411bc392afe0/out/version.expr: No such file or directory (os error 2)
--> /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rustversion-1.0.18/src/lib.rs:187:30
|
187 | const RUSTVERSION: Version = include!(concat!(env!("OUT_DIR"), "/version.expr"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `include` (in Nightly builds, run with -Z macro-backtrace for more info)
error: could not compile `rustversion` (lib) due to 1 previous error
These versions above are the first with the problem.
Are you also on Virtualbox with Windows host Linux guest?
@weihanglo Ah, yes. Windows host, Debian 12 guest, VirtualBox 7.1.4. And If I move the project to ordinary Ext4 volume, it builds successfully.
I suppose we never figured out the problem?
We kinda identified the issue happening on VirtualBox with Windows host + Linux guest when using the tempfile crate (see https://github.com/rust-lang/cargo/issues/13462#issuecomment-1972165632. I don't have the hardware and setup to root cause it and fix it. It would be much appreciated if people whose dev environment meet the requirement help with it :)
I guess that might be easy to reproduce by having a new Cargo package using tempfile and persisting the tempfile like what Cargo does in https://github.com/rust-lang/cargo/pull/12744.