Closed lukechilds closed 3 years ago
FYI: https://github.com/ZeroCostGoods/sysconf.rs/issues/19
Taking a look at it.
Annoyingly, sysconf
is needed in a single place for only one small thing. If you don't need Prometheus, then I believe the safest way to do it is to remove the body of that function and replace it with: Ok(Stats { utime: 0, rss: 0, fds: 0, })
and remove the two other references to sysconf:
Alternatively, you could try to look up the appropriate value of that constant for your libc and replace sysconf::raw::SysconfVariable::ScClkTck
with that number. You still need to remove those two other lines of course.
That's at least something you can do right now without waiting on other people. The proper fix is of course to first fix Rust libc
bindings as commented in the sysonf crate and then resolve the TODO in sysconf
itself. This should be ridiculously simple thing to do I guess apart from possible communication issues/approval process/... and waiting on others.
The tooling I'm using to create the Android build actually supports having a load of *.patch
files it'll automatically apply after pulling the source so I'll have a go at patching this on my end for now.
Thanks!
The issue is resolved for me with the following patch:
diff --git a/Cargo.toml b/Cargo.toml
index fa21354..33b9e02 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -45,7 +45,6 @@ serde_derive = "1.0"
serde_json = "1.0"
signal-hook = "0.1"
stderrlog = "0.4.1"
-sysconf = ">=0.3.4"
time = "0.1"
tiny_http = "0.6"
diff --git a/src/metrics.rs b/src/metrics.rs
index 5c678b0..6edd6ec 100644
--- a/src/metrics.rs
+++ b/src/metrics.rs
@@ -5,7 +5,6 @@ use std::io;
use std::net::SocketAddr;
use std::thread;
use std::time::Duration;
-use sysconf;
use tiny_http;
pub use prometheus::{
@@ -112,7 +111,7 @@ fn parse_stats() -> Result<Stats> {
fs::read_to_string("/proc/self/stat").chain_err(|| "failed to read /proc/self/stat")?;
let parts: Vec<&str> = value.split_whitespace().collect();
let page_size = page_size::get() as u64;
- let ticks_per_second = sysconf::raw::sysconf(sysconf::raw::SysconfVariable::ScClkTck)
+ let ticks_per_second = Ok(Stats { utime: 0, rss: 0, fds: 0, })
.expect("failed to get _SC_CLK_TCK") as f64;
let parse_part = |index: usize, name: &str| -> Result<u64> {
However now the build fails at RocksSB with:
running: "x86_64-linux-android-clang++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=x86_64-linux-android" "-fstack-protector-strong" "-Oz" "-I" "rocksdb/include/" "-I" "rocksdb/" "-I" "rocksdb/third-party/gtest-1.7.0/fused-src/" "-I" "snappy/" "-I" "lz4/lib/" "-I" "zstd/lib/" "-I" "zstd/lib/dictBuilder/" "-I" "zlib/" "-I" "bzip2/" "-I" "." "-std=c++11" "-Wno-unused-parameter" "-DSNAPPY=1" "-DLZ4=1" "-DZSTD=1" "-DZLIB=1" "-DBZIP2=1" "-DNDEBUG=1" "-DOS_LINUX=1" "-DROCKSDB_PLATFORM_POSIX=1" "-DROCKSDB_LIB_IO_POSIX=1" "-o" "/home/builder/.termux-build/electrs/src/target/x86_64-linux-android/release/build/librocksdb-sys-5700a8345e49e6ec/out/rocksdb/table/partitioned_filter_block.o" "-c" "rocksdb/table/partitioned_filter_block.cc"
cargo:warning=rocksdb/env/io_posix.cc:168:9: error: use of undeclared identifier 'fread_unlocked'
cargo:warning= r = fread_unlocked(scratch, 1, n, file_);
cargo:warning= ^
cargo:warning=1 error generated.
exit code: 1
exit code: 0
exit code: 0
exit code: 0
exit code: 0
exit code: 0
--- stderr
error occurred: Command "x86_64-linux-android-clang++" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=x86_64-linux-android" "-fstack-protector-strong" "-Oz" "-I" "rocksdb/include/" "-I" "rocksdb/" "-I" "rocksdb/third-party/gtest-1.7.0/fused-src/" "-I" "snappy/" "-I" "lz4/lib/" "-I" "zstd/lib/" "-I" "zstd/lib/dictBuilder/" "-I" "zlib/" "-I" "bzip2/" "-I" "." "-std=c++11" "-Wno-unused-parameter" "-DSNAPPY=1" "-DLZ4=1" "-DZSTD=1" "-DZLIB=1" "-DBZIP2=1" "-DNDEBUG=1" "-DOS_LINUX=1" "-DROCKSDB_PLATFORM_POSIX=1" "-DROCKSDB_LIB_IO_POSIX=1" "-o" "/home/builder/.termux-build/electrs/src/target/x86_64-linux-android/release/build/librocksdb-sys-5700a8345e49e6ec/out/rocksdb/env/io_posix.o" "-c" "rocksdb/env/io_posix.cc" with args "x86_64-linux-android-clang++" did not execute successfully (status code exit code: 1).
That patch won't compile (rustc didn't find out as it didn't hit that code yet - it was only handling the dependency before). You need to replace whole function body, not just that single line.
Looks like Android NDK doesn't provide fread_unlocked
for some reason. That's pretty strange.
You need to replace whole function body, not just that single line.
Doh! Thanks haha
Looks like Android NDK doesn't provide
fread_unlocked
for some reason. That's pretty strange.
This comment seems to suggest you could try replacing fread_unlocked
with fread
. Does that sound like a safe solution?
Obviously I can't apply a patch to a dep though so I'd have to fork it and depend on the patched fork unless there's a better solution.
Yes, it's even safer than before, but slower. :)
I could imagine forking it in such way that it could be upstreamed later, if the maintainer is interested. It should be pretty easy. add:
if cfg!(feature = "no_fread_unlocked") {
config.define("fread_unlock", Some("fread"));
}
to build_rocksdb
(notice the -sys
crate)
then add no_fread_unlocked = []
to the list of features
then you can add:
[patch.crates-io.rocksdb-sys]
git = "https://your_fork_git_repo"
to electrs Cargo
and make sure the feature is turned on by adding rocksdb-sys = { version = "YOUR_VERSION", features = ["no_fread_unlocked" ] }
to the dependencies
Edit: there's such define already but it's excluded.
I figured it out: electrs
has the version of rocksdb-sys in Cargo.lock
. We need to do cargo update
unless there's some problem with newer dependencies.
Ok, I can test that locally... will report back.
Anyway, I don't think we should lump two things under same issue. I was thinking that we could try to progress on the original one, but there seems to be something wrong, since the commit that would've fix it was reverted
And it's in libc
You could modify that patch to replace it with value 15
Hi I am running into a similar problem with sysconf
on FreeBSD -- would an acceptable solution be to add a feature flag for whatever its needed for and make it an optional dependency?
@LLFourn sadly, this can't be done in electrs
itself. We need to do it in rocksdb-sys
. The maintainers were willing to merge a contribution from me in the past, so it should be possible.
As an alternative, you could try to build dynamic (.so
) library separately and then use dynamc linking, which is now well supported.
Hi @Kixunil. I've tried to follow the instructions to build on FreeBSD 12.2 amd64 using a dynamic library but it still fails while building sysconf.
Any help appreciated.
# rustc --version
rustc 1.50.0
I have RocksDB 6.11.6 installed from Ports.
Name : rocksdb
Version : 6.11.6
Installed on : Tue Mar 16 23:20:57 2021 CET
Origin : databases/rocksdb
Architecture : FreeBSD:12:amd64
Prefix : /usr/local
Categories : databases
Licenses : GPLv2, APACHE20
Maintainer : sunpoet@FreeBSD.org
WWW : https://rocksdb.org/
Comment : Persistent key-value store for fast storage environments
Options :
DEBUG : off
LZ4 : on
ZSTD : off
I guess these are the relevant libraries and headers:
# find /usr/local/include /usr/local/lib -name \*rocks\*
/usr/local/include/rocksdb
/usr/local/include/rocksdb/rocksdb_namespace.h
/usr/local/include/rocksdb/utilities/lua/rocks_lua_util.h
/usr/local/include/rocksdb/utilities/lua/rocks_lua_custom_library.h
/usr/local/lib/librocksdb.so.6.11
/usr/local/lib/librocksdb_tools.a
/usr/local/lib/librocksdb.so.6.11.6
/usr/local/lib/librocksdb.so
/usr/local/lib/librocksdb.so.6
/usr/local/lib/librocksdb.a
Here is my build output:
# ROCKSDB_INCLUDE_DIR=/usr/local/include ROCKSDB_LIB_DIR=/usr/local/lib cargo build --locked --no-default-features --release
Compiling libc v0.2.77
Compiling autocfg v1.0.1
Compiling proc-macro2 v1.0.23
Compiling unicode-xid v0.2.1
Compiling syn v1.0.42
Compiling memchr v2.3.3
Compiling serde_derive v1.0.116
Compiling serde v1.0.116
Compiling byteorder v1.3.4
Compiling log v0.4.14
Compiling version_check v0.1.5
Compiling glob v0.2.11
Compiling version_check v0.9.2
Compiling cfg-if v1.0.0
Compiling gimli v0.22.0
Compiling adler v0.2.3
Compiling rustc-demangle v0.1.16
Compiling cfg-if v0.1.10
Compiling object v0.20.0
Compiling bitflags v1.2.1
Compiling proc-macro2 v0.4.30
Compiling lazy_static v1.4.0
Compiling unicode-xid v0.1.0
Compiling quick-error v1.2.3
Compiling regex-syntax v0.6.18
Compiling unicode-width v0.1.8
Compiling vec_map v0.8.2
Compiling typenum v1.12.0
Compiling termcolor v1.1.0
Compiling bindgen v0.47.4
Compiling strsim v0.8.0
Compiling scopeguard v0.3.3
Compiling ansi_term v0.11.0
Compiling shlex v0.1.1
Compiling peeking_take_while v0.1.2
Compiling roff v0.1.0
Compiling configure_me_codegen v0.4.0
Compiling winapi-build v0.1.1
Compiling tinyvec v0.3.4
Compiling matches v0.1.8
Compiling unicode-segmentation v1.6.0
Compiling smallvec v1.6.1
Compiling void v1.0.2
Compiling ryu v1.0.5
Compiling protobuf v2.14.0
Compiling scopeguard v1.1.0
Compiling fmt2io v0.1.0
Compiling prometheus v0.10.0
Compiling winapi v0.2.8
Compiling ahash v0.4.6
Compiling serde_json v1.0.57
Compiling percent-encoding v1.0.1
Compiling arc-swap v0.4.8
Compiling itoa v0.4.6
Compiling parse_arg v0.1.4
Compiling chunked_transfer v0.3.1
Compiling ascii v0.8.7
Compiling opaque-debug v0.3.0
Compiling cpuid-bool v0.1.2
Compiling bech32 v0.7.2
Compiling fnv v1.0.7
Compiling hex v0.3.2
Compiling glob v0.3.0
Compiling miniz_oxide v0.4.2
Compiling num-traits v0.2.12
Compiling num-integer v0.1.43
Compiling instant v0.1.9
Compiling nom v4.2.3
Compiling generic-array v0.14.4
Compiling error-chain v0.12.4
Compiling clang-sys v0.26.4
Compiling thread_local v1.0.1
Compiling humantime v1.3.0
Compiling textwrap v0.11.0
Compiling crossbeam-utils v0.6.6
Compiling addr2line v0.13.0
Compiling man v0.1.1
Compiling kernel32-sys v0.2.2
Compiling unicode-bidi v0.3.4
Compiling unicode-normalization v0.1.13
Compiling lock_api v0.4.2
Compiling hashbrown v0.9.1
Compiling crossbeam-channel v0.3.9
Compiling lru v0.6.1
Compiling idna v0.1.5
Compiling jobserver v0.1.21
Compiling atty v0.2.11
Compiling aho-corasick v0.7.13
Compiling time v0.1.44
Compiling parking_lot_core v0.8.0
Compiling dirs-sys-next v0.1.1
Compiling signal-hook-registry v1.2.1
Compiling errno v0.2.6
Compiling page_size v0.4.2
Compiling num_cpus v1.13.0
Compiling quote v1.0.7
Compiling hashbrown v0.1.8
Compiling base64 v0.10.1
Compiling quote v0.6.13
Compiling cc v1.0.60
Compiling clap v2.33.3
Compiling url v1.7.2
Compiling regex v1.3.9
Compiling parking_lot v0.11.1
Compiling dirs-next v2.0.0
Compiling signal-hook v0.1.16
Compiling backtrace v0.3.50
Compiling cexpr v0.3.6
Compiling sysconf v0.3.4
error[E0425]: cannot find value `_SC_XBS5_ILP32_OFF32` in crate `libc`
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/sysconf-0.3.4/src/raw.rs:85:28
|
85 | ScXbs5Ilp32Off32 = sc!(_SC_XBS5_ILP32_OFF32),
| ^^^^^^^^^^^^^^^^^^^^ help: a constant with a similar name exists: `_SC_V6_ILP32_OFF32`
|
::: /root/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.77/src/unix/bsd/freebsdlike/mod.rs:979:1
|
979 | pub const _SC_V6_ILP32_OFF32: ::c_int = 103;
| -------------------------------------------- similarly named constant `_SC_V6_ILP32_OFF32` defined here
error[E0425]: cannot find value `_SC_XBS5_ILP32_OFFBIG` in crate `libc`
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/sysconf-0.3.4/src/raw.rs:86:29
|
86 | ScXbs5Ilp32Offbig = sc!(_SC_XBS5_ILP32_OFFBIG),
| ^^^^^^^^^^^^^^^^^^^^^ help: a constant with a similar name exists: `_SC_V6_ILP32_OFFBIG`
|
::: /root/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.77/src/unix/bsd/freebsdlike/mod.rs:980:1
|
980 | pub const _SC_V6_ILP32_OFFBIG: ::c_int = 104;
| --------------------------------------------- similarly named constant `_SC_V6_ILP32_OFFBIG` defined here
error[E0425]: cannot find value `_SC_XBS5_LPBIG_OFFBIG` in crate `libc`
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/sysconf-0.3.4/src/raw.rs:87:29
|
87 | ScXbs5LpbigOffbig = sc!(_SC_XBS5_LPBIG_OFFBIG),
| ^^^^^^^^^^^^^^^^^^^^^ help: a constant with a similar name exists: `_SC_V6_LPBIG_OFFBIG`
|
::: /root/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.77/src/unix/bsd/freebsdlike/mod.rs:982:1
|
982 | pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 106;
| --------------------------------------------- similarly named constant `_SC_V6_LPBIG_OFFBIG` defined here
error[E0081]: discriminant value `26` already exists
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/sysconf-0.3.4/src/raw.rs:20:42
|
20 | macro_rules! sc { ($var:ident) => (libc::$var as isize) }
| ^^^^^^^^^^^^^
| |
| first use of `26`
| enum already has `26`
...
85 | ScXbs5Ilp32Off32 = sc!(_SC_XBS5_ILP32_OFF32),
| ------------------------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0081]: discriminant value `27` already exists
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/sysconf-0.3.4/src/raw.rs:20:42
|
20 | macro_rules! sc { ($var:ident) => (libc::$var as isize) }
| ^^^^^^^^^^^^^
| |
| first use of `27`
| enum already has `27`
...
86 | ScXbs5Ilp32Offbig = sc!(_SC_XBS5_ILP32_OFFBIG),
| -------------------------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0081]: discriminant value `28` already exists
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/sysconf-0.3.4/src/raw.rs:20:42
|
20 | macro_rules! sc { ($var:ident) => (libc::$var as isize) }
| ^^^^^^^^^^^^^
| |
| first use of `28`
| enum already has `28`
...
87 | ScXbs5LpbigOffbig = sc!(_SC_XBS5_LPBIG_OFFBIG),
| -------------------------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0081, E0425.
For more information about an error, try `rustc --explain E0081`.
error: could not compile `sysconf`
To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed
@ulzeraj could you try to apply this patch?
@ulzeraj could you try to apply this patch?
Thanks!
It seems to get worked until a point where it tries to use llvm-config. LLVM/Clang is the main compiler on this version of FreeBSD but apparently this tool wasn't included. I'm installing the llvm version from ports and will report back once its finished compiling.
Compiling librocksdb-sys v6.11.4
The following warnings were emitted during compilation:
warning: couldn't execute `llvm-config --prefix` (error: No such file or directory (os error 2))
warning: set the LLVM_CONFIG_PATH environment variable to the full path to a valid `llvm-config` executable (including the executable itself)
error: failed to run custom build command for `librocksdb-sys v6.11.4`
Caused by:
process didn't exit successfully: `/usr/Users/ulzeraj/electrs/target/release/build/librocksdb-sys-8059431862de149d/build-script-build` (exit code: 101)
--- stdout
cargo:warning=couldn't execute `llvm-config --prefix` (error: No such file or directory (os error 2))
cargo:warning=set the LLVM_CONFIG_PATH environment variable to the full path to a valid `llvm-config` executable (including the executable itself)
--- stderr
thread 'main' panicked at 'Unable to find libclang: "couldn\'t find any valid shared libraries matching: [\'libclang.so\', \'libclang.so.*\'], set the `LIBCLANG_PATH` environment variable to a path where one of these files can be found (invalid: [])"', /root/.cargo/registry/src/github.com-1ecc6299db9ec823/bindgen-0.54.0/src/lib.rs:1959:31
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
So what I've done so far:
llvm-90
Name : llvm
Version : 90
Installed on : Thu Mar 18 17:24:37 2021 CET
Origin : devel/llvm
Architecture : FreeBSD:12:*
Prefix : /usr/local
Categories : devel lang
Licenses : BSD2CLAUSE
Maintainer : brooks@FreeBSD.org
WWW : http://llvm.org/
Comment : Meta-port for the default version of the LLVM Toolchain
Options :
CLANG : on
EXTRAS : on
LIT : on
LLD : on
LLDB : on
The new compiler binaries will be installed on /usr/local/bin. By default the path variable sets /usr/bin before /usr/local/bin so the default compiler will take precedence over the new one so I had to run export PATH="/usr/local/bin:$PATH"
before running cargo.
Now I get this error which seems to be related to the path mentioned above. Apparently it is trying to convert the static values that replaced the sysconf code into a float.
error[E0308]: mismatched types
--> src/metrics.rs:112:46
|
112 | let ticks_per_second = Ok(Stats { utime: 0, rss: 0, fds: 0, })
| ^
| |
| expected `f64`, found integer
| help: use a float literal: `0.0`
error[E0605]: non-primitive cast: `metrics::Stats` as `f64`
--> src/metrics.rs:112:28
|
112 | let ticks_per_second = Ok(Stats { utime: 0, rss: 0, fds: 0, })
| ____________________________^
113 | | .expect("failed to get _SC_CLK_TCK") as f64;
| |___________________________________________________^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0308, E0605.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `electrs`
EDIT: sorry posted the output from an attempt to convert the values into a floating number. Fixed now.
I'm not familiar with rust but apparently Stats is a struct that has a float, an int and a memory size sort of thing:
struct Stats {
utime: f64,
rss: u64,
fds: usize,
}
So in this part utime should be something like 0.0:
let ticks_per_second = Ok(Stats { utime: 0, rss: 0, fds: 0, })
.expect("failed to get _SC_CLK_TCK") as f64;
Does ".expect("error flavor text") as f64;
" means that the code is meant to convert the results of ticks_per_second as a float? How does that work if Stats is a struct with multiple values? I don't really understand. My guess is that some stuff changed since https://github.com/romanz/electrs/issues/252#issuecomment-632162653. Also utime should be 0.0.
Sorry if those are dumb comments.
I realized by reading what I wrote that it just wants a float (sorry not a developer) so I just replaced the whole object with a float and now it builds.
--- a/src/metrics.rs 2021-03-18 19:10:20.809941000 +0100
+++ b/src/metrics.rs 2021-03-18 19:10:00.614529000 +0100
@@ -109,8 +109,7 @@
fs::read_to_string("/proc/self/stat").chain_err(|| "failed to read /proc/self/stat")?;
let parts: Vec<&str> = value.split_whitespace().collect();
let page_size = page_size::get() as u64;
- let ticks_per_second = sysconf::raw::sysconf(sysconf::raw::SysconfVariable::ScClkTck)
- .expect("failed to get _SC_CLK_TCK") as f64;
+ let ticks_per_second = 0.0;
let parse_part = |index: usize, name: &str| -> Result<u64> {
Ok(parts
Yes, that's correct. Rust is very strict about types (thank God, saved my ass so many times...), so one has to explicitly write 0.0
instead of 0
to get float. Sadly it's not always obvious to newbies what to do about it.
Oh, wait, I just realized there's division further below, so setting ticks_per_second
will cause failures in runtime. Set it to 1.0
instead.
You may be wondering how these magic numbers impact electrs
. It will not affect its essential functions, just reporting of stats using Prometheus.
0.9.0 should resolve this issue, please reopen if still relevant.
Compiling against Bionic libc with the Android NDK gives:
Looks like it's an issue with the sysconf dep. Is it possible to work around this?