diff options
-rw-r--r-- | include/erasurecode/erasurecode.h | 9 | ||||
-rw-r--r-- | include/erasurecode/erasurecode_backend.h | 2 | ||||
-rw-r--r-- | src/erasurecode.c | 51 | ||||
-rw-r--r-- | test/liberasurecode_test.c | 18 |
4 files changed, 60 insertions, 20 deletions
diff --git a/include/erasurecode/erasurecode.h b/include/erasurecode/erasurecode.h index 793b829..f8621a4 100644 --- a/include/erasurecode/erasurecode.h +++ b/include/erasurecode/erasurecode.h @@ -93,6 +93,15 @@ struct ec_args { /* liberasurecode frontend API functions */ /** + * Checks if a given backend is available. + * + * @param backend_id - one of the supported backends. + * + * @returns 1 if a backend is available; 0 otherwise + */ +int liberasurecode_backend_available(const ec_backend_id_t backend_id); + +/** * Create a liberasurecode instance and return a descriptor * for use with EC operations (encode, decode, reconstruct) * diff --git a/include/erasurecode/erasurecode_backend.h b/include/erasurecode/erasurecode_backend.h index d62c6fb..4199344 100644 --- a/include/erasurecode/erasurecode_backend.h +++ b/include/erasurecode/erasurecode_backend.h @@ -142,7 +142,7 @@ int liberasurecode_backend_instance_unregister(ec_backend_t instance); /* Generic dlopen/dlclose routines */ -int liberasurecode_backend_open(ec_backend_t instance); +void* liberasurecode_backend_open(ec_backend_t instance); int liberasurecode_backend_close(ec_backend_t instance); diff --git a/src/erasurecode.c b/src/erasurecode.c index 13e5f02..6528eec 100644 --- a/src/erasurecode.c +++ b/src/erasurecode.c @@ -168,21 +168,10 @@ static void print_dlerror(const char *caller) } /* Generic dlopen/dlclose routines */ -int liberasurecode_backend_open(ec_backend_t instance) +void* liberasurecode_backend_open(ec_backend_t instance) { - if (instance && NULL != instance->desc.backend_sohandle) - return 0; - /* Use RTLD_LOCAL to avoid symbol collisions */ - instance->desc.backend_sohandle = dlopen(instance->common.soname, - RTLD_LAZY | RTLD_LOCAL); - if (NULL == instance->desc.backend_sohandle) { - print_dlerror(__func__); - return -EBACKENDNOTAVAIL; - } - - dlerror(); /* Clear any existing errors */ - return 0; + return dlopen(instance->common.soname, RTLD_LAZY | RTLD_LOCAL); } int liberasurecode_backend_close(ec_backend_t instance) @@ -226,6 +215,28 @@ liberasurecode_exit(void) { /* =~=*=~==~=*=~= liberasurecode frontend API implementation =~=*=~==~=*=~== */ /** + * Checks if a given backend is available. + * + * @param backend_id - one of the supported backends. + * + * @returns 1 if a backend is available; 0 otherwise + */ +int liberasurecode_backend_available(const ec_backend_id_t backend_id) { + struct ec_backend backend; + if (backend_id >= EC_BACKENDS_MAX) + return 0; + + backend.desc.backend_sohandle = liberasurecode_backend_open( + ec_backends_supported[backend_id]); + if (!backend.desc.backend_sohandle) { + return 0; + } + + liberasurecode_backend_close(&backend); + return 1; +} + +/** * Create a liberasurecode instance and return a descriptor * for use with EC operations (encode, decode, reconstruct) * @@ -247,7 +258,6 @@ liberasurecode_exit(void) { int liberasurecode_instance_create(const ec_backend_id_t id, struct ec_args *args) { - int err = 0; ec_backend_t instance = NULL; struct ec_backend_args bargs; if (!args) @@ -274,11 +284,14 @@ int liberasurecode_instance_create(const ec_backend_id_t id, /* Open backend .so if not already open */ /* .so handle is returned in instance->desc.backend_sohandle */ - err = liberasurecode_backend_open(instance); - if (err < 0) { - /* ignore during init, return the same handle */ - free(instance); - return err; + if (!instance->desc.backend_sohandle) { + instance->desc.backend_sohandle = liberasurecode_backend_open(instance); + if (!instance->desc.backend_sohandle) { + /* ignore during init, return the same handle */ + print_dlerror(__func__); + free(instance); + return -EBACKENDNOTAVAIL; + } } /* Call private init() for the backend */ diff --git a/test/liberasurecode_test.c b/test/liberasurecode_test.c index e8b3179..8ee84c4 100644 --- a/test/liberasurecode_test.c +++ b/test/liberasurecode_test.c @@ -471,6 +471,16 @@ static void test_create_and_destroy_backend( assert(0 == liberasurecode_instance_destroy(desc)); } +static void test_backend_available(ec_backend_id_t be_id) { + assert(1 == liberasurecode_backend_available(be_id)); +} + +static void test_backend_available_invalid_args(ec_backend_id_t be_id) +{ + int ret = liberasurecode_backend_available(EC_BACKENDS_MAX); + assert(ret < 0); +} + static void test_create_backend_invalid_args() { int desc = liberasurecode_instance_create(-1, &null_args); @@ -1522,6 +1532,14 @@ static void test_verify_stripe_metadata_frag_idx_invalid( //static void test_verify_str struct testcase testcases[] = { + {"test_backend_available_invalid_args", + test_backend_available_invalid_args, + EC_BACKENDS_MAX, 0, + .skip = false}, + {"test_backend_available", + test_backend_available, + EC_BACKEND_NULL, 0, + .skip = false}, {"test_create_backend_invalid_args", test_create_backend_invalid_args, EC_BACKENDS_MAX, CHKSUM_TYPES_MAX, |