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

Cargo gets lost in the root of a Linux filesystem #9528

Closed
ehuss opened this issue May 31, 2021 · 3 comments · Fixed by #10188
Closed

Cargo gets lost in the root of a Linux filesystem #9528

ehuss opened this issue May 31, 2021 · 3 comments · Fixed by #10188
Labels
A-rebuild-detection Area: rebuild detection and fingerprinting C-bug Category: bug E-medium Experience: Medium

Comments

@ehuss
Copy link
Contributor

ehuss commented May 31, 2021

Problem
cargo doc will mysteriously hang when run from the root of a Linux filesystem. The problem is that the fingerprinting code tries to find the file with the newest mtime by walking the entire filesystem. Unfortunately there are some paths that are infinite black holes.

An example is /sys/block. This tree has a complex set of cyclical symbolic links. Cargo follows a cycle until it reaches ELOOP (too many symbolic links), and then starts following another cycle. There is a permutation of cycles, and so cargo essentially gets lost forever.

I believe this also affects "old" style build scripts which also use LocalFingerprint::Precalculated.

Steps

  1. Start a bash prompt with the rust:latest docker image.
  2. In the root directory, run cargo init --name foo
  3. Run cargo doc. This step will never finish.

Possible Solution(s)
Uncertain. A few ideas:

  • Use walkdir for walking, which has symbolic link cycle detection.
  • Check for special devices and ignore them.
  • Detect running in root, and return an error.
  • Set an upper bound on the number of files the walker will visit before it gives up.

As a side note, another problem with the implementation is that it collects the path of every file it visits in memory. This is done with the assumption that PathSource::list_files will return a reasonable number of files. However, the mtime computation code doesn't need a full list, but instead just needs to know which file has the newest mtime. Perhaps that code could be changed to take a callback instead of accumulating all the files in memory.

Notes

Output of cargo version:
cargo 1.54.0-nightly (e931e47 2021-05-24)

Linux 4.19.121

@ehuss ehuss added C-bug Category: bug A-rebuild-detection Area: rebuild detection and fingerprinting labels May 31, 2021
@jyn514
Copy link
Member

jyn514 commented Jul 8, 2021

@ehuss it seems strange to me that cargo looks at all files in the first place - I can look into adding --emit=dep-info to rustdoc if that would help.

@weihanglo
Copy link
Member

Perhaps that code could be changed to take a callback instead of accumulating all the files in memory.

I prototyped an iterative version, but I don't feel comfortable about its complexity. 😞
Is there anything can do to make it simpler?

@bors bors closed this as completed in b05697d Dec 16, 2021
bors added a commit that referenced this issue Jan 5, 2022
Be resilient to most IO error and filesystem loop while walking dirs

Let `PathSource::walk` be resilient to most IO errors and filesystem loop.

This PR also

- Add a test validating the resilience against filesystem loop to prevent regression.
- Emit warning when filesystem loop found while walking the filesystem. This is the only way I can think of now to solve #9528

Fixes #10213.
weihanglo pushed a commit to weihanglo/cargo that referenced this issue Jan 12, 2022
…alexcrichton

Be resilient to most IO error and filesystem loop while walking dirs

Let `PathSource::walk` be resilient to most IO errors and filesystem loop.

This PR also

- Add a test validating the resilience against filesystem loop to prevent regression.
- Emit warning when filesystem loop found while walking the filesystem. This is the only way I can think of now to solve rust-lang#9528

Fixes rust-lang#10213.
@LizardWizzard
Copy link

LizardWizzard commented May 2, 2024

Faced the same issue during cargo build when I copy sources into root in docker. I see endless wall of warnings with the original repro.

Workaround for me was to create directory and copy sources there instead of root.

Will it be better to terminate with an error instead of being stuck ~forever with warnings?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rebuild-detection Area: rebuild detection and fingerprinting C-bug Category: bug E-medium Experience: Medium
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants