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

compiler wrapper trying to create temporary files in /dev #2288

Open
mischief opened this issue Nov 16, 2024 · 4 comments
Open

compiler wrapper trying to create temporary files in /dev #2288

mischief opened this issue Nov 16, 2024 · 4 comments

Comments

@mischief
Copy link

hi,

without any additional setup or ceremony, i built HEAD with rustc/cargo 1.81.0 in gentoo and invoked sccache like the readme suggests: https://github.com/mozilla/sccache?tab=readme-ov-file#usage

mischief@beast:~/src/sccache $ cargo build --release
   Compiling libc v0.2.155
   Compiling proc-macro2 v1.0.75
   Compiling unicode-ident v1.0.12
...
    Finished `release` profile [optimized] target(s) in 3m 24s

i'm not a rust person, but i find it odd that sccache would attempt to make a temporary file in /dev/. a user program should never do this.

this occurred after more than 1 invocation of sccache with the same parameters. the first invocation had no error.

mischief@beast:~/src/sccache $ ./target/release/sccache cc -o /dev/null -c ~/code/c/fbufsize.c
sccache: encountered fatal error
sccache: error: Permission denied (os error 13) at path "/dev/.tmp48KCJX"
sccache: caused by: Permission denied (os error 13) at path "/dev/.tmp48KCJX"

fbufsize.c is nothing special, just a trivial program i had laying around.

#include <stdio.h>
#include <stdio_ext.h>

int main(void)
{
        setvbuf(stdout, NULL, _IONBF, 0);
        setvbuf(stderr, NULL, _IONBF, 0);
        printf("%ld\n", __fbufsize(stdout));
        printf("%ld\n", __fbufsize(stderr));
        return 0;
}
@Xuanwo
Copy link
Collaborator

Xuanwo commented Nov 16, 2024

./target/release/sccache cc -o /dev/null -c ~/code/c/fbufsize.c

Hi, what will happen if we change -o /dev/null?

@myzhang1029
Copy link

myzhang1029 commented Mar 15, 2025

Can reproduce this with a simpler file

int main(){}

@Xuanwo -o /dev/null is often hardcoded into scripts like ./configure and cannot be changed easily. IMHO it would be nice for sccache to support this use case.

After some tracing, this originated in server code. If there is a cache hit (inside get_cached_or_compile), control passes to extract_objects, which "Write the cache entry to a tempfile and then atomically move it to its final location so that other rustc invocations happening in parallel don't see a partially-written file."

It makes sense to put this temp file in the same directory as the actual output most of the time, but it doesn't work for /dev/null. Would it be possible to use a different temporary directory when this happens?

EDIT: probably not. This would defeat the purpose of introducing a move because cross-device move can't be atomic.

A dirtier workaround for this specific case:

diff --git a/src/cache/cache.rs b/src/cache/cache.rs
index c56f522..8242167 100644
--- a/src/cache/cache.rs
+++ b/src/cache/cache.rs
@@ -207,6 +207,10 @@ impl CacheRead {
                 optional,
             } in objects
             {
+                if path == Path::new("/dev/null") {
+                    debug!("Skipping output to /dev/null");
+                    continue;
+                }
                 let dir = match path.parent() {
                     Some(d) => d,
                     None => bail!("Output file without a parent directory!"),

@mischief
Copy link
Author

why would sccache need to do this if the compilers it is wrapping doesn't? seems like an easy fix.

@myzhang1029
Copy link

myzhang1029 commented Mar 19, 2025

I understand their justification of an atomic fs move operation, but I feel like rustc accessing a half-written file itself is a bug in rustc/cargo instead of something sccache should solve. (i.e. depending processes shouldn't have even started until the dependent process ended).

This change originated in 16ecd0b and was subsequently moved to cache/cache.rs in 8a85b5f.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants