Skip to content
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

"Invalid cross-device link" when generating query files #2663

Closed
lheckemann opened this issue Jul 28, 2023 · 7 comments · Fixed by #2803
Closed

"Invalid cross-device link" when generating query files #2663

lheckemann opened this issue Jul 28, 2023 · 7 comments · Fixed by #2803
Labels

Comments

@lheckemann
Copy link

Bug Description

When CARGO_TARGET_DIR is not on the same filesystem as the project source, cargo sqlx prepare fails:

error: failed to move query file: PersistError(Os { code: 18, kind: CrossesDevices, message: "Invalid cross-device link" })

Minimal Reproduction

(on linux)

  1. Mount a tmpfs somewhere, e.g. sudo mount -o X-mount.mkdir /tmp/cargo-target-dir
  2. Use this as CARGO_TARGET_DIR while running cargo sqlx prepare.

Info

  • SQLx version: 0.7.0
  • SQLx features enabled: features = ["postgres", "runtime-tokio-rustls", "chrono", "uuid"]
  • Database server and version: postgres (PostgreSQL) 14.8
  • Operating system: NixOS
  • rustc --version: rustc 1.71.0 (8ede3aae2 2023-07-12)
@lheckemann lheckemann added the bug label Jul 28, 2023
@lheckemann
Copy link
Author

Similar to #2395.

@mattfbacon
Copy link
Contributor

I'm also encountering this issue. The whole idea of using a temporary file and then persisting it doesn't make any sense to me. Why not just serialize the data into memory and then write it out directly to the "persisted" location? I'll look into making a PR to do that instead.

@abonander
Copy link
Collaborator

@mattfbacon

Why not just serialize the data into memory and then write it out directly to the "persisted" location?

Because it is the recommended way to ensure the write is atomic. If the same query appears in multiple places, then multiple instances of the macro may attempt to write the data file at the same time. This may be a non-issue for invocations within the same crate as macros are expanded serially, but could be an issue for concurrent compiler invocations when building a multi-crate project.

@mattfbacon
Copy link
Contributor

That can be handled with the O_EXCL flag to open.

@abonander
Copy link
Collaborator

abonander commented Sep 27, 2023

The manpage for open() says of O_EXCL:

When these two flags are specified, symbolic links are not followed: if pathname is a symbolic link, then open() fails regardless of where the symbolic link points.

Does this apply if the parent directory is a symbolic link as might also happen?

@mattfbacon
Copy link
Contributor

No, it works fine in that case. Also, it's in the Rust stdlib as OpenOptions::create_new.

mattfbacon added a commit to mattfbacon/sqlx that referenced this issue Sep 28, 2023
@mattfbacon
Copy link
Contributor

I just pushed a PR that uses OpenOptions::create_new.

abonander pushed a commit that referenced this issue Oct 17, 2023
* Don't use temp dir for query jsons

Fixes #2663

* Return early when exclusive create fails

* Use atomic-file-write for writing query data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants