diff --git a/.travis.yml b/.travis.yml index 86931c4..9f01a0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,11 @@ rust: - nightly before_script: + - ./install_dependent_libraries.sh - rustup component add clippy-preview script: - - cargo test -- --test-threads=1 + - cargo test - cargo clippy matrix: @@ -19,4 +20,6 @@ matrix: env: global: - - RUSTFLAGS="-D warnings" + - FRUGALOS_DIR=$TRAVIS_BUILD_DIR/frugalos_working_dir + - LD_LIBRARY_PATH=$FRUGALOS_DIR/lib + - RUSTFLAGS="-D warnings" diff --git a/Cargo.toml b/Cargo.toml index b75b56a..9582eba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,8 +2,6 @@ name = "liberasurecode" version = "1.0.2" authors = ["The FrugalOS Developers"] -links = "erasurecode" -build = "build.rs" description = "A Rust wrapper for `openstack/liberasurecode`" homepage = "https://github.com/frugalos/liberasurecode" repository = "https://github.com/frugalos/liberasurecode" diff --git a/README.md b/README.md index 354a415..fd2f655 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,16 @@ For example, on Ubuntu, you can install those by executing the following command $ sudo apt install gcc git make automake autoconf libtool ``` +Before do `cargo build`, please set the two environment variables `FRUGALOS_DIR` and `LD_LIBRARY_PATH` +``` +FRUGALOS_DIR=/some/path/to/locate/generated/artifacts +LD_LIBRARY_PATH=$FRUGALOS_DIR/lib +``` +and do the following shell script to install auxiliary files +``` +./install_dependent_libraries.sh +``` + Examples -------- diff --git a/build.rs b/build.rs index 660a5de..4730497 100644 --- a/build.rs +++ b/build.rs @@ -1,37 +1,10 @@ use std::env; -use std::fs; -use std::path::PathBuf; -use std::process::{Command, Stdio}; fn main() { println!("cargo:rerun-if-changed=build.rs"); - let outdir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - let build_dir = outdir.join("build"); - let _ = fs::remove_dir_all(&build_dir); - fs::create_dir(&build_dir).unwrap(); + let frugalos_dir: std::ffi::OsString = env::var_os("FRUGALOS_DIR").unwrap(); + let frugalos_dir: String = frugalos_dir.into_string().unwrap(); - for file in &["install_deps.sh", "liberasurecode.patch"] { - fs::copy(file, build_dir.join(file)).unwrap(); - } - - match Command::new("./install_deps.sh") - .current_dir(&build_dir) - .stderr(Stdio::inherit()) - .output() - { - Err(e) => { - panic!("{}: {}", build_dir.display(), e); - } - Ok(output) => { - if !output.status.success() { - panic!( - "./install_deps.sh failed: exit-code={:?}", - output.status.code() - ); - } - } - } - - println!("cargo:rustc-link-search={}/lib", build_dir.display()); + println!("cargo:rustc-link-search={}/lib", frugalos_dir); } diff --git a/install_dependent_libraries.sh b/install_dependent_libraries.sh new file mode 100755 index 0000000..0d03cb0 --- /dev/null +++ b/install_dependent_libraries.sh @@ -0,0 +1,68 @@ +#! /usr/bin/env bash + +set -eux + +INSTALL_DIR="" + +if [ -z $FRUGALOS_DIR ] +then + echo "Please set the environment FRUGALOS_DIR to install auxiliary artifacts." + exit 1 +fi + +INSTALL_DIR=$FRUGALOS_DIR + +case $INSTALL_DIR in + /*) + echo "We install dependent artifacts into FRUGALOS_DIR=$FRUGALOS_DIR" + ;; + *) + echo "You passed a relative path. Please use an absolute path." + exit 1 + ;; +esac + +MAKE_FLAGS="" + +# Please try and add other distributions. +case "$(uname)" in + "Linux") MAKE_FLAGS="-j$(nproc)";; + "Darwin") MAKE_FLAGS="-j$(sysctl -n hw.ncpu)" +esac + +BUILD_DIR="build_working_directory" +mkdir $BUILD_DIR + +# +# gf-complete +# +git clone https://github.com/ceph/gf-complete.git $BUILD_DIR/gf-complete +cd $BUILD_DIR/gf-complete +git checkout a6862d1 +./autogen.sh +./configure --with-pic --prefix $INSTALL_DIR +make $MAKE_FLAGS install +cd ../.. + +# +# jerasure +# +git clone -b frugalos_dyn https://github.com/frugalos/jerasure.git $BUILD_DIR/jerasure +cd $BUILD_DIR/jerasure +autoreconf --force --install +CFLAGS="-I${INSTALL_DIR}/include" LDFLAGS="-L${INSTALL_DIR}/lib" ./configure --with-pic --prefix $INSTALL_DIR +make $MAKE_FLAGS install +cd ../.. + +# +# liberasurecode +# +git clone -b frugalos_dyn https://github.com/frugalos/openstack_liberasurecode.git $BUILD_DIR/openstack_liberasurecode +cd $BUILD_DIR/openstack_liberasurecode +./autogen.sh +CFLAGS="-I${INSTALL_DIR}/include -I${INSTALL_DIR}/include/jerasure" +if [ "$(uname)" == "Darwin" ]; then + CFLAGS="$CFLAGS -Wno-error=address-of-packed-member" +fi +CFLAGS=$CFLAGS LDFLAGS="-L${INSTALL_DIR}/lib" ./configure --with-pic --prefix $INSTALL_DIR +make $MAKE_FLAGS install diff --git a/install_deps.sh b/install_deps.sh index 2f49927..049c581 100755 --- a/install_deps.sh +++ b/install_deps.sh @@ -18,32 +18,29 @@ git clone https://github.com/ceph/gf-complete.git cd gf-complete/ git checkout a6862d1 ./autogen.sh -./configure --disable-shared --with-pic --prefix $BUILD_DIR +./configure --with-pic --prefix $BUILD_DIR make $MAKE_FLAGS install cd ../ # # jerasure # -git clone https://github.com/ceph/jerasure.git +git clone -b frugalos_dyn https://github.com/frugalos/jerasure.git cd jerasure/ -git checkout de1739c autoreconf --force --install -CFLAGS="-I${BUILD_DIR}/include" LDFLAGS="-L${BUILD_DIR}/lib" ./configure --disable-shared --enable-static --with-pic --prefix $BUILD_DIR +CFLAGS="-I${BUILD_DIR}/include" LDFLAGS="-L${BUILD_DIR}/lib" ./configure --with-pic --prefix $BUILD_DIR make $MAKE_FLAGS install cd ../ # # liberasurecode # -git clone https://github.com/openstack/liberasurecode.git -cd liberasurecode/ -git checkout 1.5.0 +git clone -b frugalos_dyn https://github.com/frugalos/openstack_liberasurecode.git +cd openstack_liberasurecode/ ./autogen.sh CFLAGS="-I${BUILD_DIR}/jerasure/include -I${BUILD_DIR}/include" if [ "$(uname)" == "Darwin" ]; then CFLAGS="$CFLAGS -Wno-error=address-of-packed-member" fi -CFLAGS=$CFLAGS LIBS="-lJerasure" LDFLAGS="-L${BUILD_DIR}/lib" ./configure --disable-shared --with-pic --prefix $BUILD_DIR -patch -p1 < ../liberasurecode.patch # Applies a patch for building static library +CFLAGS=$CFLAGS LDFLAGS="-L${BUILD_DIR}/lib" ./configure --with-pic --prefix $BUILD_DIR make $MAKE_FLAGS install diff --git a/liberasurecode.patch b/liberasurecode.patch deleted file mode 100644 index 2e848b5..0000000 --- a/liberasurecode.patch +++ /dev/null @@ -1,425 +0,0 @@ -diff --git a/include/erasurecode/alg_sig.h b/include/erasurecode/alg_sig.h -index 52554a9..0a6863d 100644 ---- a/include/erasurecode/alg_sig.h -+++ b/include/erasurecode/alg_sig.h -@@ -44,7 +44,6 @@ typedef struct alg_sig_s - int gf_w; - int sig_len; - struct jerasure_mult_routines mult_routines; -- void *jerasure_sohandle; - int *tbl1_l; - int *tbl1_r; - int *tbl2_l; -diff --git a/src/backends/jerasure/jerasure_rs_cauchy.c b/src/backends/jerasure/jerasure_rs_cauchy.c -index 3a0365a..217413d 100644 ---- a/src/backends/jerasure/jerasure_rs_cauchy.c -+++ b/src/backends/jerasure/jerasure_rs_cauchy.c -@@ -28,6 +28,8 @@ - - #include - #include -+#include -+#include - - #include "erasurecode.h" - #include "erasurecode_backend.h" -@@ -268,87 +270,16 @@ static void * jerasure_rs_cauchy_init(struct ec_backend_args *args, - } - } - -- /* -- * ISO C forbids casting a void* to a function pointer. -- * Since dlsym return returns a void*, we use this union to -- * "transform" the void* to a function pointer. -- */ -- union { -- cauchy_original_coding_matrix_func initp; -- jerasure_matrix_to_bitmatrix_func matrixtobitmatrixp; -- jerasure_smart_bitmatrix_to_schedule_func matrixschedulep; -- galois_uninit_field_func uninitp; -- jerasure_bitmatrix_encode_func encodep; -- jerasure_bitmatrix_decode_func decodep; -- jerasure_erasures_to_erased_func erasedp; -- jerasure_make_decoding_bitmatrix_func decodematrixp; -- jerasure_bitmatrix_dotprod_func dotprodp; -- void *vptr; -- } func_handle = {.vptr = NULL}; -- - /* fill in function addresses */ -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_bitmatrix_encode"); -- desc->jerasure_bitmatrix_encode = func_handle.encodep; -- if (NULL == desc->jerasure_bitmatrix_encode) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_bitmatrix_decode"); -- desc->jerasure_bitmatrix_decode = func_handle.decodep; -- if (NULL == desc->jerasure_bitmatrix_decode) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "cauchy_original_coding_matrix"); -- desc->cauchy_original_coding_matrix = func_handle.initp; -- if (NULL == desc->cauchy_original_coding_matrix) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_matrix_to_bitmatrix"); -- desc->jerasure_matrix_to_bitmatrix = func_handle.matrixtobitmatrixp; -- if (NULL == desc->jerasure_matrix_to_bitmatrix) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_smart_bitmatrix_to_schedule"); -- desc->jerasure_smart_bitmatrix_to_schedule = func_handle.matrixschedulep; -- if (NULL == desc->jerasure_smart_bitmatrix_to_schedule) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_make_decoding_bitmatrix"); -- desc->jerasure_make_decoding_bitmatrix = func_handle.decodematrixp; -- if (NULL == desc->jerasure_make_decoding_bitmatrix) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_bitmatrix_dotprod"); -- desc->jerasure_bitmatrix_dotprod = func_handle.dotprodp; -- if (NULL == desc->jerasure_bitmatrix_dotprod) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_erasures_to_erased"); -- desc->jerasure_erasures_to_erased = func_handle.erasedp; -- if (NULL == desc->jerasure_erasures_to_erased) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "galois_uninit_field"); -- desc->galois_uninit_field = func_handle.uninitp; -- if (NULL == desc->galois_uninit_field) { -- goto error; -- } -+ desc->jerasure_bitmatrix_encode = jerasure_bitmatrix_encode; -+ desc->jerasure_bitmatrix_decode = jerasure_bitmatrix_decode; -+ desc->cauchy_original_coding_matrix = cauchy_original_coding_matrix; -+ desc->jerasure_matrix_to_bitmatrix = jerasure_matrix_to_bitmatrix; -+ desc->jerasure_smart_bitmatrix_to_schedule = jerasure_smart_bitmatrix_to_schedule; -+ desc->jerasure_make_decoding_bitmatrix = jerasure_make_decoding_bitmatrix; -+ desc->jerasure_bitmatrix_dotprod = jerasure_bitmatrix_dotprod; -+ desc->jerasure_erasures_to_erased = jerasure_erasures_to_erased; -+ desc->galois_uninit_field = (galois_uninit_field_func)galois_uninit_field; - - /* setup the Cauchy matrices and schedules */ - desc->matrix = desc->cauchy_original_coding_matrix(k, m, w); -diff --git a/src/backends/jerasure/jerasure_rs_vand.c b/src/backends/jerasure/jerasure_rs_vand.c -index 9395046..143e00f 100644 ---- a/src/backends/jerasure/jerasure_rs_vand.c -+++ b/src/backends/jerasure/jerasure_rs_vand.c -@@ -28,6 +28,8 @@ - - #include - #include -+#include -+#include - - #include "erasurecode.h" - #include "erasurecode_backend.h" -@@ -232,98 +234,40 @@ static void * jerasure_rs_vand_init(struct ec_backend_args *args, - } - } - -- /* -- * ISO C forbids casting a void* to a function pointer. -- * Since dlsym return returns a void*, we use this union to -- * "transform" the void* to a function pointer. -- */ -- union { -- reed_sol_vandermonde_coding_matrix_func initp; -- galois_uninit_field_func uninitp; -- jerasure_matrix_encode_func encodep; -- jerasure_matrix_decode_func decodep; -- jerasure_make_decoding_matrix_func decodematrixp; -- jerasure_erasures_to_erased_func erasep; -- jerasure_matrix_dotprod_func dotprodp; -- void *vptr; -- } func_handle = {.vptr = NULL}; -- -- - /* fill in function addresses */ -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_matrix_encode"); -- desc->jerasure_matrix_encode = func_handle.encodep; -- if (NULL == desc->jerasure_matrix_encode) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_matrix_decode"); -- desc->jerasure_matrix_decode = func_handle.decodep; -- if (NULL == desc->jerasure_matrix_decode) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_make_decoding_matrix"); -- desc->jerasure_make_decoding_matrix = func_handle.decodematrixp; -- if (NULL == desc->jerasure_make_decoding_matrix) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_matrix_dotprod"); -- desc->jerasure_matrix_dotprod = func_handle.dotprodp; -- if (NULL == desc->jerasure_matrix_dotprod) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "jerasure_erasures_to_erased"); -- desc->jerasure_erasures_to_erased = func_handle.erasep; -- if (NULL == desc->jerasure_erasures_to_erased) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "reed_sol_vandermonde_coding_matrix"); -- desc->reed_sol_vandermonde_coding_matrix = func_handle.initp; -- if (NULL == desc->reed_sol_vandermonde_coding_matrix) { -- goto error; -- } -- -- func_handle.vptr = NULL; -- func_handle.vptr = dlsym(backend_sohandle, "galois_uninit_field"); -- desc->galois_uninit_field = func_handle.uninitp; -- if (NULL == desc->galois_uninit_field) { -- goto error; -- } -+ desc->jerasure_matrix_encode = jerasure_matrix_encode; -+ desc->jerasure_matrix_decode = jerasure_matrix_decode; -+ desc->jerasure_make_decoding_matrix = jerasure_make_decoding_matrix; -+ desc->jerasure_matrix_dotprod = jerasure_matrix_dotprod; -+ desc->jerasure_erasures_to_erased = jerasure_erasures_to_erased; -+ desc->reed_sol_vandermonde_coding_matrix = reed_sol_vandermonde_coding_matrix; -+ desc->galois_uninit_field = (galois_uninit_field_func)galois_uninit_field; - - desc->matrix = desc->reed_sol_vandermonde_coding_matrix( - desc->k, desc->m, desc->w); - if (NULL == desc->matrix) { -- goto error; -+ goto error; - } - - return desc; - - error: - free(desc); -- -+ - return NULL; - } - - /** -- * Return the element-size, which is the number of bits stored -- * on a given device, per codeword. For Vandermonde, this is -- * 'w'. For somthing like cauchy, this is packetsize * w. -- * -+ * Return the element-size, which is the number of bits stored -+ * on a given device, per codeword. For Vandermonde, this is -+ * 'w'. For somthing like cauchy, this is packetsize * w. -+ * - * Returns the size in bits! - */ - static int - jerasure_rs_vand_element_size(void* desc) - { -- struct jerasure_rs_vand_descriptor *jerasure_desc = -+ struct jerasure_rs_vand_descriptor *jerasure_desc = - (struct jerasure_rs_vand_descriptor*)desc; - - /* Note that cauchy will return pyeclib_handle->w * PYECC_CAUCHY_PACKETSIZE * 8 */ -diff --git a/src/erasurecode.c b/src/erasurecode.c -index fb6d5de..4c3d024 100644 ---- a/src/erasurecode.c -+++ b/src/erasurecode.c -@@ -177,6 +177,9 @@ void* liberasurecode_backend_open(ec_backend_t instance) - { - if (NULL == instance) - return NULL; -+ if (strncmp(instance->common.soname, "libJerasure", 11) == 0) -+ return (void *)-1; -+ - /* Use RTLD_LOCAL to avoid symbol collisions */ - return dlopen(instance->common.soname, RTLD_LAZY | RTLD_LOCAL); - } -@@ -186,6 +189,9 @@ int liberasurecode_backend_close(ec_backend_t instance) - if (NULL == instance || NULL == instance->desc.backend_sohandle) - return 0; - -+ if (strncmp(instance->common.soname, "libJerasure", 11) == 0) -+ return 0; -+ - dlclose(instance->desc.backend_sohandle); - dlerror(); /* Clear any existing errors */ - -diff --git a/src/utils/chksum/alg_sig.c b/src/utils/chksum/alg_sig.c -index 86740e6..bee5fca 100644 ---- a/src/utils/chksum/alg_sig.c -+++ b/src/utils/chksum/alg_sig.c -@@ -27,52 +27,27 @@ - #include - #include - #include --#define GALOIS_SINGLE_MULTIPLY "galois_single_multiply" --#define GALOIS_UNINIT "galois_uninit_field" -+#include -+#define GALOIS_SINGLE_MULTIPLY galois_single_multiply -+#define GALOIS_UNINIT galois_uninit_field - - int valid_gf_w[] = { 8, 16, -1 }; - int valid_pairs[][2] = { { 8, 32}, {16, 32}, {16, 64}, {-1, -1} }; - --galois_single_multiply_func get_galois_multi_func(void *handle) { -- /* -- * ISO C forbids casting a void* to a function pointer. -- * Since dlsym return returns a void*, we use this union to -- * "transform" the void* to a function pointer. -- */ -- union { -- galois_single_multiply_func fptr; -- void *vptr; -- } func_handle = {.vptr = NULL}; -- func_handle.vptr = dlsym(handle, GALOIS_SINGLE_MULTIPLY); -- return func_handle.fptr; -+galois_single_multiply_func get_galois_multi_func() { -+ return (galois_single_multiply_func)GALOIS_SINGLE_MULTIPLY; - } - - void stub_galois_uninit_field(int w){} - --galois_uninit_field_func get_galois_uninit_func(void *handle) { -- /* -- * ISO C forbids casting a void* to a function pointer. -- * Since dlsym return returns a void*, we use this union to -- * "transform" the void* to a function pointer. -- */ -- union { -- galois_uninit_field_func fptr; -- void *vptr; -- } func_handle = {.vptr = NULL}; -- func_handle.vptr = dlsym(handle, GALOIS_UNINIT); -- return func_handle.fptr; --} -- -- --void *get_jerasure_sohandle() --{ -- return dlopen(JERASURE_SONAME, RTLD_LAZY | RTLD_LOCAL); -+galois_uninit_field_func get_galois_uninit_func() { -+ return (galois_uninit_field_func)GALOIS_UNINIT; - } - --int load_gf_functions(void *sohandle, struct jerasure_mult_routines *routines) -+int load_gf_functions(struct jerasure_mult_routines *routines) - { -- routines->galois_single_multiply = get_galois_multi_func(sohandle); -- routines->galois_uninit_field = get_galois_uninit_func(sohandle); -+ routines->galois_single_multiply = get_galois_multi_func(); -+ routines->galois_uninit_field = get_galois_uninit_func(); - if (NULL == routines->galois_single_multiply) { - return -1; - } -@@ -93,7 +68,7 @@ int load_gf_functions(void *sohandle, struct jerasure_mult_routines *routines) - } - - static --alg_sig_t *init_alg_sig_w8(void *jerasure_sohandle, int sig_len) -+alg_sig_t *init_alg_sig_w8(int sig_len) - { - alg_sig_t *alg_sig_handle; - int num_gf_lr_table_syms; -@@ -107,9 +82,7 @@ alg_sig_t *init_alg_sig_w8(void *jerasure_sohandle, int sig_len) - return NULL; - } - -- alg_sig_handle->jerasure_sohandle = jerasure_sohandle; -- -- if (load_gf_functions(alg_sig_handle->jerasure_sohandle, &(alg_sig_handle->mult_routines)) < 0) { -+ if (load_gf_functions(&(alg_sig_handle->mult_routines)) < 0) { - free(alg_sig_handle); - return NULL; - } -@@ -150,7 +123,7 @@ alg_sig_t *init_alg_sig_w8(void *jerasure_sohandle, int sig_len) - } - - static --alg_sig_t *init_alg_sig_w16(void *jerasure_sohandle, int sig_len) -+alg_sig_t *init_alg_sig_w16(int sig_len) - { - alg_sig_t *alg_sig_handle; - int num_gf_lr_table_syms; -@@ -159,18 +132,12 @@ alg_sig_t *init_alg_sig_w16(void *jerasure_sohandle, int sig_len) - int alpha = 2, beta = 4, gamma = 8; - int num_components = sig_len / w; - -- if (NULL == jerasure_sohandle) { -- return NULL; -- } -- - alg_sig_handle = (alg_sig_t *)malloc(sizeof(alg_sig_t)); - if (NULL == alg_sig_handle) { - return NULL; - } - -- alg_sig_handle->jerasure_sohandle = jerasure_sohandle; -- -- if (load_gf_functions(alg_sig_handle->jerasure_sohandle, &(alg_sig_handle->mult_routines)) < 0) { -+ if (load_gf_functions(&(alg_sig_handle->mult_routines)) < 0) { - free(alg_sig_handle); - return NULL; - } -@@ -216,15 +183,9 @@ alg_sig_t *init_alg_sig_w16(void *jerasure_sohandle, int sig_len) - alg_sig_t *init_alg_sig(int sig_len, int gf_w) - { - int i=0; -- void *jerasure_sohandle = get_jerasure_sohandle(); -- -- if (NULL == jerasure_sohandle) { -- fprintf (stderr, "Could not open Jerasure backend. Install Jerasure or fix LD_LIBRARY_PATH. Passing.\n"); -- return NULL; -- } - - while (valid_pairs[i][0] > -1) { -- if (gf_w == valid_pairs[i][0] && -+ if (gf_w == valid_pairs[i][0] && - sig_len == valid_pairs[i][1]) { - break; - } -@@ -236,9 +197,9 @@ alg_sig_t *init_alg_sig(int sig_len, int gf_w) - } - - if (gf_w == 8) { -- return init_alg_sig_w8(jerasure_sohandle, sig_len); -+ return init_alg_sig_w8(sig_len); - } else if (gf_w == 16) { -- return init_alg_sig_w16(jerasure_sohandle, sig_len); -+ return init_alg_sig_w16(sig_len); - } - return NULL; - } -@@ -254,7 +215,6 @@ void destroy_alg_sig(alg_sig_t* alg_sig_handle) - } - - alg_sig_handle->mult_routines.galois_uninit_field(alg_sig_handle->gf_w); -- dlclose(alg_sig_handle->jerasure_sohandle); - - int num_components = alg_sig_handle->sig_len / alg_sig_handle->gf_w; - diff --git a/src/c_api.rs b/src/c_api.rs index f7136d2..56868d5 100644 --- a/src/c_api.rs +++ b/src/c_api.rs @@ -43,10 +43,10 @@ pub const EINVALIDPARAMS: u32 = 206; pub const EBADHEADER: u32 = 207; pub const EINSUFFFRAGS: u32 = 208; -#[link(name = "erasurecode", kind = "static")] -#[link(name = "gf_complete", kind = "static")] -#[link(name = "Jerasure", kind = "static")] -#[link(name = "Xorcode", kind = "static")] +#[link(name = "erasurecode")] +#[link(name = "gf_complete")] +#[link(name = "FrugalosJerasure")] +#[link(name = "Xorcode")] extern "C" { /// Create a liberasurecode instance and return a descriptor /// for use with EC operations (encode, decode, reconstruct) diff --git a/src/lib.rs b/src/lib.rs index 928788d..085b3fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,6 @@ extern crate libc; use std::num::NonZeroUsize; use std::slice; -use std::time::Duration; pub use result::{Error, Result}; @@ -63,6 +62,9 @@ pub enum Backend { /// Cauchy base Read-Solomon erasure coding provided by `jerasure` library (default). JerasureRsCauchy, + + /// Read-Solomon erasure coding built-in `openstack/liberasurecode`. + LibErasureCodeRsVand, } impl Default for Backend { /// `Backend::JerasureRsCauchy`を返す. @@ -143,6 +145,7 @@ impl Builder { let backend_id = match self.backend { Backend::JerasureRsCauchy => c_api::EcBackendId::JERASURE_RS_CAUCHY, Backend::JerasureRsVand => c_api::EcBackendId::JERASURE_RS_VAND, + Backend::LibErasureCodeRsVand => c_api::EcBackendId::LIBERASURECODE_RS_VAND, }; let checksum_type = match self.checksum { Checksum::None => c_api::EcChecksumType::NONE, @@ -171,10 +174,6 @@ impl Builder { parity_fragments: self.parity_fragments, desc, }).map_err(Error::from_error_code)?; - - // `SIGSEGV` may be raised if encodings are executed (in parallel) immediately after creation. - // To prevent it, sleeps the current thread for a little while. - std::thread::sleep(Duration::from_millis(10)); Ok(coder) }) } @@ -295,7 +294,9 @@ impl ErasureCoder { } impl Drop for ErasureCoder { fn drop(&mut self) { - let _ = c_api::instance_destroy(self.desc); + with_global_lock(|| { + let _ = c_api::instance_destroy(self.desc); + }) } } @@ -384,7 +385,13 @@ mod tests { #[test] fn various_params() { - for backend in [Backend::JerasureRsCauchy, Backend::JerasureRsVand].iter() { + for backend in [ + Backend::JerasureRsCauchy, + Backend::JerasureRsVand, + Backend::LibErasureCodeRsVand, + ] + .iter() + { for checksum in [Checksum::None, Checksum::Crc32, Checksum::Md5].iter() { for data_fragments in (3..6).map(non_zero) { for parity_fragments in (1..4).map(non_zero) {