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

rust: Allow to specify a separate download folder for rust packages #22457

Closed
wants to merge 1 commit into from

Conversation

feckert
Copy link
Member

@feckert feckert commented Oct 20, 2023

Maintainer: @jefferyto
Compile tested: x86_64, -- , OpenWrt master
Run tested: not needed only build changes

Description:
By default, the rust downloads are stored in the rustc/cargo subdirectory of the openwrt default download folder. However, this can cause problems if the download directory is not local but is an nfs mount.

Fix this by adding a new configuration option to openwrt to change the default download folder for rust packages.

My research has shown that the problem is the nfs mount.

Build error if dl ist on a ntfs mount:

   Compiling xz2 v0.1.7
   Compiling build_helper v0.1.0 (/home/bbworker/bbworker/owrt_dev_x86_64/System6/build/openwrt/build_dir/target-x86_64_musl/host/rustc-1.73.0-src/src/tools/build_helper)
    Finished dev [unoptimized] target(s) in 17.44s
downloading https://ci-artifacts.rust-lang.org/rustc-builds/cc66ad468955717ab92600c770da8c1601a4ff33/rust-dev-1.73.0-x86_64-unknown-linux-gnu.tar.xz
#=#=#                                                                         
##                                                                         3.7%
#####                                                                      8.1%
#########                                                                 12.6%
############                                                              17.0%
###############                                                           21.7%
##################                                                        26.2%
######################                                                    30.6%
#########################                                                 35.1%
############################                                              39.5%
###############################                                           44.0%
##################################                                        48.4%
#####################################                                     52.5%
########################################                                  56.7%
###########################################                               61.1%
###############################################                           65.3%
##################################################                        69.7%
#####################################################                     74.0%
########################################################                  78.3%
###########################################################               82.7%
##############################################################            87.1%
#################################################################         91.3%
####################################################################      95.6%
#######################################################################   99.8%
######################################################################## 100.0%
thread 'main' panicked at 'std::fs::rename(&tempfile, dest_path) failed with Invalid cross-device link (os error 18)', download.rs:205:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Build completed unsuccessfully in 0:00:27
make[4]: *** [Makefile:108: /home/bbworker/bbworker/owrt_dev_x86_64/System6/build/openwrt/build_dir/target-x86_64_musl/host/rustc-1.73.0-src/.built] Error 1
time: package/feeds/packages/rust/host-compile#65.55#10.02#35.76

By default, the rust downloads are stored in the rustc/cargo subdirectory of
the openwrt default download folder. However, this can cause problems
if the download directory is not local but is an nfs mount.

Fix this by adding a new configuration option to openwrt to change the
default download folder for rust packages.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
@jefferyto
Copy link
Member

This looks like an issue caused by 0002-rustc-bootstrap-cache.patch - can you try replacing that patch with this:

--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -546,7 +546,7 @@ class RustBuild(object):
                 shutil.rmtree(bin_root)
 
             key = self.stage0_compiler.date
-            cache_dst = os.path.join(self.build_dir, "cache")
+            cache_dst = os.getenv('OPENWRT_RUSTC_BOOTSTRAP_CACHE', os.path.join(self.build_dir, "cache"))
             rustc_cache = os.path.join(cache_dst, key)
             if not os.path.exists(rustc_cache):
                 os.makedirs(rustc_cache)
--- a/src/bootstrap/download.rs
+++ b/src/bootstrap/download.rs
@@ -202,7 +202,13 @@ impl Config {
             Some(other) => panic!("unsupported protocol {other} in {url}"),
             None => panic!("no protocol in {url}"),
         }
-        t!(std::fs::rename(&tempfile, dest_path));
+        match std::fs::rename(&tempfile, dest_path) {
+            Ok(v) => v,
+            Err(_) => {
+                t!(std::fs::copy(&tempfile, dest_path));
+                t!(std::fs::remove_file(&tempfile));
+            }
+        }
     }
 
     fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
@@ -520,7 +526,10 @@ impl Config {
         key: &str,
         destination: &str,
     ) {
-        let cache_dst = self.out.join("cache");
+        let cache_dst = match env::var_os("OPENWRT_RUSTC_BOOTSTRAP_CACHE") {
+            Some(v) => PathBuf::from(v),
+            None => self.out.join("cache"),
+        };
         let cache_dir = cache_dst.join(key);
         if !cache_dir.exists() {
             t!(fs::create_dir_all(&cache_dir));
@@ -647,7 +656,10 @@ download-rustc = false
         let llvm_assertions = self.llvm_assertions;
 
         let cache_prefix = format!("llvm-{llvm_sha}-{llvm_assertions}");
-        let cache_dst = self.out.join("cache");
+        let cache_dst = match env::var_os("OPENWRT_RUSTC_BOOTSTRAP_CACHE") {
+            Some(v) => PathBuf::from(v),
+            None => self.out.join("cache"),
+        };
         let rustc_cache = cache_dst.join(cache_prefix);
         if !rustc_cache.exists() {
             t!(fs::create_dir_all(&rustc_cache));

@jefferyto
Copy link
Member

I have tested this patch with OPENWRT_RUSTC_BOOTSTRAP_CACHE set to a different mount point. I don't have a nfs mount to test with though; if this works for you I'll open a PR with this change.

@feckert
Copy link
Member Author

feckert commented Oct 23, 2023

@jefferyto thanks for your reply and your suggested change.
It seems to work via nfs. But now I can not restart an already builded openwrt build tree.
I always get the following error:

 feckert@feckert01  ~/workspace/openwrt/LDM-master-x86_64/build/openwrt   patched  make ./package/feeds/packages/rust/host/compile V=s
make[2]: Entering directory '/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/scripts/config'
make[2]: 'conf' is up to date.
make[2]: Leaving directory '/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/scripts/config'
make[1]: Entering directory '/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt'
make[2]: Entering directory '/home/feckert/workspace/openwrt/LDM-master-x86_64/build/feeds/packages/lang/rust'
(cd /home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/build_dir/target-x86_64_musl/host/rustc-1.73.0-src/; if [ -x configure ]; then cp -fpR /home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/scripts/config.{guess,sub} /home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/build_dir/target-x86_64_musl/host/rustc-1.73.0-src// && CC="/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/host/bin/gcc" CFLAGS="-O2 -I/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/host/include -I/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/hostpkg/include -I/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/target-x86_64_musl/host/include" CXX="/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/host/bin/g++" CPPFLAGS="-I/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/host/include -I/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/hostpkg/include -I/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/target-x86_64_musl/host/include" CXXFLAGS="" LDFLAGS="-L/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/host/lib -L/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/hostpkg/lib -L/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/target-x86_64_musl/host/lib" CONFIG_SHELL="/usr/bin/env bash" CARGO_HOME="/home/feckert/dl/cargo"  bash ./configure --build=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-musl,x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --prefix=/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/target-x86_64_musl/host --bindir=/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/target-x86_64_musl/host/bin --libdir=/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/target-x86_64_musl/host/lib --sysconfdir=/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/target-x86_64_musl/host/etc --datadir=/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/target-x86_64_musl/host/share --mandir=/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/target-x86_64_musl/host/man --dist-compression-formats=gz --enable-missing-tools --disable-sanitizers --release-channel=stable --enable-cargo-native-static --set=llvm.download-ci-llvm=true --set=target.x86_64-unknown-linux-musl.ar=x86_64-openwrt-linux-musl-gcc-ar --set=target.x86_64-unknown-linux-musl.cc=x86_64-openwrt-linux-musl-gcc --set=target.x86_64-unknown-linux-musl.cxx=x86_64-openwrt-linux-musl-g++ --set=target.x86_64-unknown-linux-musl.linker=x86_64-openwrt-linux-musl-gcc --set=target.x86_64-unknown-linux-musl.ranlib=x86_64-openwrt-linux-musl-gcc-ranlib --set=target.x86_64-unknown-linux-musl.crt-static=false --set=target.x86_64-unknown-linux-musl.musl-root=/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/staging_dir/toolchain-x86_64_gcc-12.3.0_musl ; fi )

configure: ERROR: Existing 'config.toml' detected. Exiting

make[2]: *** [Makefile:108: /home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/build_dir/target-x86_64_musl/host/rustc-1.73.0-src/.configured] Error 1
make[2]: Leaving directory '/home/feckert/workspace/openwrt/LDM-master-x86_64/build/feeds/packages/lang/rust'
time: package/feeds/packages/rust/host-compile#0.11#0.31#0.60
    ERROR: package/feeds/packages/rust [host] failed to build.
make[1]: *** [package/Makefile:118: package/feeds/packages/rust/host/compile] Error 1
make[1]: Leaving directory '/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt'
make: *** [/home/feckert/workspace/openwrt/LDM-master-x86_64/build/openwrt/include/toplevel.mk:232: package/feeds/packages/rust/host/compile] Error 2

If I remove the config.toml file in the /target-x86_64_musl/host/rustc-1.73.0-src/ directory I could rebuild the tree and the error is gone. I have to this every time on rebouild?

Another problem has arised with a rust package that was not presented before. So I think this is related to your suggested change.

  Installing netavark v1.8.0 (/home/bbworker/bbworker/owrt_master_x86_64/System6/build/openwrt/build_dir/target-x86_64_musl/netavark-1.8.0)
    Updating crates.io index
 Downloading crates ...
error: failed to compile `netavark v1.8.0 (/home/bbworker/bbworker/owrt_master_x86_64/System6/build/openwrt/build_dir/target-x86_64_musl/netavark-1.8.0)`, intermediate artifacts can be found at `/home/bbworker/bbworker/owrt_master_x86_64/System6/build/openwrt/build_dir/target-x86_64_musl/netavark-1.8.0/target`.
To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.
Caused by:
  failed to download `clap v4.3.24`
Caused by:
  unable to get packages from source
Caused by:
  failed to download replaced source registry `crates-io`
Caused by:
  failed to unpack package `clap v4.3.24`
Caused by:
  failed to open `/home/bbworker/dl/cargo/registry/src/index.crates.io-6f17d22bba15001f/clap-4.3.24/.cargo-ok`
Caused by:
  File exists (os error 17)
make[4]: *** [Makefile:55: /home/bbworker/bbworker/owrt_master_x86_64/System6/build/openwrt/build_dir/target-x86_64_musl/netavark-1.8.0/.built] Error 101
time: package/feeds/packages/netavark/compile#0.42#0.16#5.39

@jefferyto
Copy link
Member

If I remove the config.toml file in the /target-x86_64_musl/host/rustc-1.73.0-src/ directory I could rebuild the tree and the error is gone. I have to this every time on rebouild?

If rust/host was already built then nothing should happen when you try to build it a second time. Are .configured and .built files created correctly in /target-x86_64_musl/host/rustc-1.73.0-src/?

Another problem has arised with a rust package that was not presented before. So I think this is related to your suggested change.

This isn't related to my suggested changed. (The patch is for caching downloads during rust/host build; this error is during build for a package that uses rust/host.) This might be related to having CARGO_HOME in a nfs mount. Do you see the same error when building other rust packages? Does it reoccur if you delete the entire cargo directory (in /home/bbworker/dl)?

jefferyto added a commit to jefferyto/openwrt-packages that referenced this pull request Oct 26, 2023
The rust bootstrap downloads files into a "tmp" directory then moves the
files into the "cache" directory using std::fs::rename. There are no
issues in the original/unpatched case as "tmp" and "cache" are
subdirectories in the build directory ($(HOST_BUILD_DIR)/build) and so
are nearly guaranteed to be on the same filesystem.

35768bf changed where files are
saved/cached (in $(DL_DIR)/rustc). If HOST_BUILD_DIR and DL_DIR are on
separate filesystems, then using std::fs::rename to move the files will
fail.[1]

This updates 0002-rustc-bootstrap-cache.patch to account for this case,
i.e. if std::fs::rename fails, fall back to copying the file then
removing the original.

[1]: openwrt#22457

Fixes: 35768bf ("rust: Cache bootstrap downloads to $(DL_DIR)/rustc")

Signed-off-by: Jeffery To <jeffery.to@gmail.com>
@feckert
Copy link
Member Author

feckert commented Oct 27, 2023

I am still testing. I will report in the other pullrequest whether it fixes my problem. I am therefore closing the pullrequest. Thanks for your feedback

@feckert feckert closed this Oct 27, 2023
neheb pushed a commit that referenced this pull request Oct 30, 2023
The rust bootstrap downloads files into a "tmp" directory then moves the
files into the "cache" directory using std::fs::rename. There are no
issues in the original/unpatched case as "tmp" and "cache" are
subdirectories in the build directory ($(HOST_BUILD_DIR)/build) and so
are nearly guaranteed to be on the same filesystem.

35768bf changed where files are
saved/cached (in $(DL_DIR)/rustc). If HOST_BUILD_DIR and DL_DIR are on
separate filesystems, then using std::fs::rename to move the files will
fail.[1]

This updates 0002-rustc-bootstrap-cache.patch to account for this case,
i.e. if std::fs::rename fails, fall back to copying the file then
removing the original.

[1]: #22457

Fixes: 35768bf ("rust: Cache bootstrap downloads to $(DL_DIR)/rustc")

Signed-off-by: Jeffery To <jeffery.to@gmail.com>
jefferyto added a commit to jefferyto/openwrt-packages that referenced this pull request Oct 31, 2023
The rust bootstrap downloads files into a "tmp" directory then moves the
files into the "cache" directory using std::fs::rename. There are no
issues in the original/unpatched case as "tmp" and "cache" are
subdirectories in the build directory ($(HOST_BUILD_DIR)/build) and so
are nearly guaranteed to be on the same filesystem.

35768bf changed where files are
saved/cached (in $(DL_DIR)/rustc). If HOST_BUILD_DIR and DL_DIR are on
separate filesystems, then using std::fs::rename to move the files will
fail.[1]

This updates 0002-rustc-bootstrap-cache.patch to account for this case,
i.e. if std::fs::rename fails, fall back to copying the file then
removing the original.

[1]: openwrt#22457

Fixes: 35768bf ("rust: Cache bootstrap downloads to $(DL_DIR)/rustc")

Signed-off-by: Jeffery To <jeffery.to@gmail.com>
(cherry picked from commit f9f1e02)
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

Successfully merging this pull request may close these issues.

2 participants