diff --git a/examples/c/ADM_register_job.c b/examples/c/ADM_register_job.c index b1b9926ce6ae3be533b9114463c9fbd55554515b..9f2806874e919d7945907f5b44b9e6734097190d 100644 --- a/examples/c/ADM_register_job.c +++ b/examples/c/ADM_register_job.c @@ -8,7 +8,7 @@ int main(int argc, char* argv[]) { - if(argc != 3) { + if(argc != 2) { fprintf(stderr, "ERROR: no location provided\n"); fprintf(stderr, "Usage: ADM_register_job \n"); exit(EXIT_FAILURE); @@ -24,7 +24,7 @@ main(int argc, char* argv[]) { for(int i = 0; i < NINPUTS; ++i) { const char* pattern = "input-dataset-%d"; size_t n = snprintf(NULL, 0, pattern, i); - char* id = (char*) malloc(n + 1); + char* id = (char*) alloca(n + 1); snprintf(id, n + 1, pattern, i); inputs[i] = ADM_dataset_create(id); } @@ -34,13 +34,18 @@ main(int argc, char* argv[]) { for(int i = 0; i < NOUTPUTS; ++i) { const char* pattern = "output-dataset-%d"; size_t n = snprintf(NULL, 0, pattern, i); - char* id = (char*) malloc(n + 1); + char* id = (char*) alloca(n + 1); snprintf(id, n + 1, pattern, i); outputs[i] = ADM_dataset_create(id); } - ADM_job_requirements_t reqs = ADM_job_requirements_create( - inputs, NINPUTS, outputs, NOUTPUTS, NULL); + ADM_adhoc_context_t ctx = ADM_adhoc_context_create( + ADM_ADHOC_MODE_SEPARATE_NEW, ADM_ADHOC_ACCESS_RDWR, 42, 100, false); + + ADM_storage_t st = ADM_storage_create("foobar", ADM_STORAGE_GEKKOFS, ctx); + + ADM_job_requirements_t reqs = + ADM_job_requirements_create(inputs, NINPUTS, outputs, NOUTPUTS, st); ADM_return_t ret = ADM_register_job(server, reqs, &job); if(ret != ADM_SUCCESS) { @@ -63,6 +68,8 @@ cleanup: ADM_dataset_destroy(outputs[i]); } + // ADM_adhoc_context_destroy(ctx); + ADM_server_destroy(server); exit(exit_status); } diff --git a/examples/cxx/ADM_register_adhoc_storage.cpp b/examples/cxx/ADM_register_adhoc_storage.cpp index f97aa69257198270e24698bd84c638ef09145384..44b875236511b18dc2f292cd61fd723e2b740c28 100644 --- a/examples/cxx/ADM_register_adhoc_storage.cpp +++ b/examples/cxx/ADM_register_adhoc_storage.cpp @@ -5,37 +5,29 @@ int main(int argc, char* argv[]) { - if(argc != 3) { + if(argc != 2) { fmt::print(stderr, "ERROR: no location provided\n"); - fmt::print(stderr, "Usage: ADM_register_adhoc_storage " - "\n"); + fmt::print(stderr, "Usage: ADM_register_adhoc_storage \n"); exit(EXIT_FAILURE); } admire::server server{"tcp", argv[1]}; - - ADM_job_t job{}; - ADM_adhoc_context_t ctx{}; - ADM_storage_t adhoc_storage{}; - ADM_return_t ret = ADM_SUCCESS; + admire::job job{42}; + admire::adhoc_storage::context ctx{"in_job:shared", "write-only", 10, 10, false}; + admire::adhoc_storage adhoc_storage{"read-only", 10, ctx}; try { - ret = admire::register_adhoc_storage(server, job, ctx, &adhoc_storage); - } catch(const std::exception& e) { - fmt::print(stderr, "FATAL: ADM_register_adhoc_storage() failed: {}\n", - e.what()); - exit(EXIT_FAILURE); - } - if(ret != ADM_SUCCESS) { - fmt::print( - stdout, - "ADM_register_adhoc_storage() remote procedure not completed " - "successfully\n"); + [[maybe_unused]] const auto ret = admire::register_adhoc_storage(server, job, ctx, &adhoc_storage); + + // do something with job. name changed to ret to not create conflict. + // TODO: name changed from job to ret to not create conflict. + + fmt::print(stdout, "ADM_register_adhoc_storage() remote procedure completed " + "successfully\n"); + exit(EXIT_SUCCESS); + } catch(const std::exception& e) { + fmt::print(stderr, "FATAL: ADM_register_adhoc_storage() failed: {}\n", e.what()); exit(EXIT_FAILURE); } - - fmt::print(stdout, - "ADM_register_adhoc_storage() remote procedure completed " - "successfully\n"); } diff --git a/examples/cxx/ADM_register_job.cpp b/examples/cxx/ADM_register_job.cpp index 5001058b58cbb77d501d289af7159028a26c7bb8..89c99f25e12039bc124da49ce4f1a110facb1d4c 100644 --- a/examples/cxx/ADM_register_job.cpp +++ b/examples/cxx/ADM_register_job.cpp @@ -1,19 +1,33 @@ #include #include +#define NINPUTS 10 +#define NOUTPUTS 5 int main(int argc, char* argv[]) { - if(argc != 3) { - fmt::print(stderr, "ERROR: no location provided\n"); - fmt::print(stderr, "Usage: ADM_register_job \n"); + if(argc != 2) { + fmt::print(stderr, "ERROR: no server address provided\n"); + fmt::print(stderr, "Usage: ADM_register_job \n"); exit(EXIT_FAILURE); } admire::server server{"tcp", argv[1]}; - ADM_job_requirements_t reqs{}; + std::vector inputs; + inputs.reserve(NINPUTS); + for(int i = 0; i < NINPUTS; ++i) { + inputs.emplace_back(fmt::format("input-dataset-{}", i)); + } + + std::vector outputs; + outputs.reserve(NOUTPUTS); + for(int i = 0; i < NOUTPUTS; ++i) { + outputs.emplace_back(fmt::format("output-dataset-{}", i)); + } + + admire::job_requirements reqs{inputs, outputs}; try { diff --git a/examples/cxx/ADM_remove_job.cpp b/examples/cxx/ADM_remove_job.cpp index fc037a10e8f6b7f34adec1e400515c7cbc858aba..1b4b3427b8301bb947d4ad9f55a525cc2a006c24 100644 --- a/examples/cxx/ADM_remove_job.cpp +++ b/examples/cxx/ADM_remove_job.cpp @@ -5,30 +5,27 @@ int main(int argc, char* argv[]) { - if(argc != 3) { + if(argc != 2) { fmt::print(stderr, "ERROR: no location provided\n"); - fmt::print(stderr, "Usage: ADM_remove_job \n"); + fmt::print(stderr, "Usage: ADM_remove_job \n"); exit(EXIT_FAILURE); } admire::server server{"tcp", argv[1]}; - - ADM_job_t job{}; - ADM_return_t ret = ADM_SUCCESS; + admire::job job{42}; try { - ret = admire::remove_job(server, job); - } catch(const std::exception& e) { - fmt::print(stderr, "FATAL: ADM_remove_job() failed: {}\n", e.what()); - exit(EXIT_FAILURE); - } - if(ret != ADM_SUCCESS) { - fmt::print(stdout, "ADM_remove_job() remote procedure not completed " + [[maybe_unused]] const auto ret = admire::remove_job(server, job); + + // do something with job. name changed to ret to not create conflict. + // TODO: name changed from job to ret to not create conflict. + + fmt::print(stdout, "ADM_remove_job() remote procedure completed " "successfully\n"); + exit(EXIT_SUCCESS); + } catch(const std::exception& e) { + fmt::print(stderr, "FATAL: ADM_remove_job() failed: {}\n", e.what()); exit(EXIT_FAILURE); } - - fmt::print(stdout, "ADM_remove_job() remote procedure completed " - "successfully\n"); } diff --git a/examples/cxx/ADM_update_job.cpp b/examples/cxx/ADM_update_job.cpp index 5b579eb46e6e22ab96236a5825638514723a5275..ff5e77a06e8b7ac4f68a0a7228efc89e303eaf24 100644 --- a/examples/cxx/ADM_update_job.cpp +++ b/examples/cxx/ADM_update_job.cpp @@ -1,35 +1,48 @@ #include #include +#define NINPUTS 10 +#define NOUTPUTS 5 int main(int argc, char* argv[]) { - if(argc != 3) { - fmt::print(stderr, "ERROR: no location provided\n"); - fmt::print(stderr, "Usage: ADM_update_job \n"); + if(argc != 2) { + fmt::print(stderr, "ERROR: no server address provided\n"); + fmt::print(stderr, "Usage: ADM_update_job \n"); exit(EXIT_FAILURE); } admire::server server{"tcp", argv[1]}; - ADM_job_t job{}; - ADM_job_requirements_t reqs{}; - ADM_return_t ret = ADM_SUCCESS; + std::vector inputs; + inputs.reserve(NINPUTS); + for(int i = 0; i < NINPUTS; ++i) { + inputs.emplace_back(fmt::format("input-dataset-{}", i)); + } - try { - ret = admire::update_job(server, job, reqs); - } catch(const std::exception& e) { - fmt::print(stderr, "FATAL: ADM_update_job() failed: {}\n", e.what()); - exit(EXIT_FAILURE); + std::vector outputs; + outputs.reserve(NOUTPUTS); + for(int i = 0; i < NOUTPUTS; ++i) { + outputs.emplace_back(fmt::format("output-dataset-{}", i)); } - if(ret != ADM_SUCCESS) { - fmt::print(stdout, "ADM_update_job() remote procedure not completed " + admire::job_requirements reqs{inputs, outputs}; + admire::job job{42}; + + try { + + [[maybe_unused]] const auto ret = admire::update_job(server, job, reqs); + + // do something with job. + // TODO: name changed from job to ret to not create conflict. + + fmt::print(stdout, "ADM_update_job() remote procedure completed " "successfully\n"); + exit(EXIT_SUCCESS); + } catch(const std::exception& e) { + fmt::print(stderr, "FATAL: ADM_update_job() failed: {}\n", e.what()); exit(EXIT_FAILURE); } - - fmt::print(stdout, "ADM_update_job() remote procedure completed " - "successfully\n"); } + diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index f3fbb8b22569acb1ebb1998ba0efddb01dd6bb25..92460cc99a7b6735818951d335b65ed7a3ee2cef 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -37,10 +37,15 @@ add_subdirectory(logger) target_include_directories(_logger INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(common::logger ALIAS _logger) -add_subdirectory(network) +add_subdirectory(net) target_include_directories(_network_engine INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(common::network::engine ALIAS _network_engine) target_include_directories(_rpc_server INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(common::network::rpc_server ALIAS _rpc_server) + + +target_include_directories(_rpc_types INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}) +add_library(common::network::rpc_types ALIAS _rpc_types) diff --git a/src/common/network/CMakeLists.txt b/src/common/net/CMakeLists.txt similarity index 98% rename from src/common/network/CMakeLists.txt rename to src/common/net/CMakeLists.txt index 5aa5930d8f503db018442e559298c0468453c441..63049547aac98586d530a23ba99760e284b7c6a0 100644 --- a/src/common/network/CMakeLists.txt +++ b/src/common/net/CMakeLists.txt @@ -43,3 +43,5 @@ target_sources( ) target_link_libraries(_rpc_server PUBLIC common::config _network_engine) + +add_subdirectory(proto) diff --git a/src/common/network/detail/address.hpp b/src/common/net/detail/address.hpp similarity index 100% rename from src/common/network/detail/address.hpp rename to src/common/net/detail/address.hpp diff --git a/src/common/network/engine.hpp b/src/common/net/engine.hpp similarity index 99% rename from src/common/network/engine.hpp rename to src/common/net/engine.hpp index 19e4fb700b86541255120c75a97b5a050a04e634..c241f8a130e1ea294387bfa0d2b88e768413366e 100644 --- a/src/common/network/engine.hpp +++ b/src/common/net/engine.hpp @@ -58,6 +58,7 @@ namespace detail { } \ } +#define _handler_for___null NULL struct margo_context { diff --git a/src/scord-ctl/rpcs/CMakeLists.txt b/src/common/net/proto/CMakeLists.txt similarity index 82% rename from src/scord-ctl/rpcs/CMakeLists.txt rename to src/common/net/proto/CMakeLists.txt index ae011dd902d58b27184e3eae3df59649c7c09742..f7697d3ed03b0c64490266843970a5d3b52691dc 100644 --- a/src/scord-ctl/rpcs/CMakeLists.txt +++ b/src/common/net/proto/CMakeLists.txt @@ -22,10 +22,15 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ -add_library(scord_private_rpcs STATIC) -target_sources(scord_private_rpcs - PRIVATE private.cpp private.hpp) +add_library(_rpc_types STATIC) -target_include_directories(scord_private_rpcs INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(scord_private_rpcs PUBLIC common::logger Margo::Margo) -set_property(TARGET scord_private_rpcs PROPERTY POSITION_INDEPENDENT_CODE ON) +set_property(TARGET _rpc_types PROPERTY POSITION_INDEPENDENT_CODE ON) + +target_include_directories(_rpc_types PUBLIC ${CMAKE_SOURCE_DIR}/src/lib) +target_sources( + _rpc_types + PRIVATE rpc_types.h rpc_types.c ${CMAKE_SOURCE_DIR}/src/lib/admire.h + ${CMAKE_SOURCE_DIR}/src/lib/admire_types.h +) + +target_link_libraries(_rpc_types PRIVATE Mercury::Mercury Margo::Margo) diff --git a/src/common/net/proto/rpc_types.c b/src/common/net/proto/rpc_types.c new file mode 100644 index 0000000000000000000000000000000000000000..4727173cf5a4dbf3cfed223c8044bb3d163604b8 --- /dev/null +++ b/src/common/net/proto/rpc_types.c @@ -0,0 +1,285 @@ +/****************************************************************************** + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + +#include "rpc_types.h" + +hg_return_t +hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data) { + hg_return_t ret = HG_SUCCESS; + ADM_dataset_list_t* list = (ADM_dataset_list_t*) data; + ADM_dataset_list_t tmp = NULL; + + hg_size_t length = 0; + + switch(hg_proc_get_op(proc)) { + + case HG_ENCODE: + tmp = *list; + // write the length of the list + length = tmp->l_length; + ret = hg_proc_hg_size_t(proc, &tmp->l_length); + + if(ret != HG_SUCCESS) { + break; + } + + // write the list + for(size_t i = 0; i < length; ++i) { + ret = hg_proc_adm_dataset(proc, &tmp->l_datasets[i]); + + if(ret != HG_SUCCESS) { + break; + } + } + break; + + case HG_DECODE: { + + // find out the length of the list + ret = hg_proc_hg_size_t(proc, &length); + + if(ret != HG_SUCCESS) { + break; + } + + // loop and create list elements + tmp = (ADM_dataset_list_t) calloc(1, + sizeof(struct adm_dataset_list)); + tmp->l_length = length; + tmp->l_datasets = + (adm_dataset*) calloc(length, sizeof(adm_dataset)); + + for(size_t i = 0; i < length; ++i) { + ret = hg_proc_adm_dataset(proc, &tmp->l_datasets[i]); + + if(ret != HG_SUCCESS) { + break; + } + } + + // return the newly-created list + *list = tmp; + + break; + } + + case HG_FREE: + tmp = *list; + free(tmp->l_datasets); + free(tmp); + ret = HG_SUCCESS; + break; + } + + return ret; +} + + +hg_return_t +hg_proc_ADM_storage_t(hg_proc_t proc, void* data) { + (void) proc; + (void) data; + + hg_return_t ret = HG_SUCCESS; + ADM_storage_t* storage = (ADM_storage_t*) data; + ADM_storage_t tmp = NULL; + hg_size_t storage_length = 0; + + switch(hg_proc_get_op(proc)) { + + case HG_ENCODE: + // find out the length of the adm_storage object we need to send + storage_length = *storage ? sizeof(adm_storage) : 0; + ret = hg_proc_hg_size_t(proc, &storage_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!storage_length) { + return HG_SUCCESS; + } + + // if we actually need to send an adm_storage object, + // write each of its fields to the mercury buffer + tmp = *storage; + + // 1. the storage type + ret = hg_proc_hg_uint32_t(proc, &tmp->s_type); + + if(ret != HG_SUCCESS) { + break; + } + + // 2. the storage id + ret = hg_proc_hg_const_string_t(proc, &tmp->s_id); + + if(ret != HG_SUCCESS) { + break; + } + + // 3. the appropriate storage context + switch(tmp->s_type) { + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + ret = hg_proc_adm_adhoc_context(proc, &tmp->s_adhoc_ctx); + break; + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + ret = hg_proc_adm_pfs_context(proc, &tmp->s_adhoc_ctx); + break; + } + + break; + + case HG_DECODE: + // find out the length of the adm_storage object + ret = hg_proc_hg_size_t(proc, &storage_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!storage_length) { + *storage = NULL; + break; + } + + // if the received adm_storage object was not NULL, read each of + // its fields from the mercury buffer + tmp = (adm_storage*) calloc(1, sizeof(adm_storage)); + + // 1. the storage type + ret = hg_proc_uint32_t(proc, &tmp->s_type); + + if(ret != HG_SUCCESS) { + break; + } + + // 2. the storage id + ret = hg_proc_hg_const_string_t(proc, &tmp->s_id); + + if(ret != HG_SUCCESS) { + break; + } + + // 3. the appropriate storage context + switch(tmp->s_type) { + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + ret = hg_proc_adm_adhoc_context(proc, &tmp->s_adhoc_ctx); + break; + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + ret = hg_proc_adm_pfs_context(proc, &tmp->s_adhoc_ctx); + break; + } + + // return the newly-created ctx + *storage = tmp; + break; + + case HG_FREE: + tmp = *storage; + free(tmp); + break; + } + + return ret; +} + +hg_return_t +hg_proc_ADM_adhoc_context_t(hg_proc_t proc, void* data) { + + hg_return_t ret = HG_SUCCESS; + ADM_adhoc_context_t* ctx = (ADM_adhoc_context_t*) data; + ADM_adhoc_context_t tmp = NULL; + hg_size_t ctx_length = 0; + + switch(hg_proc_get_op(proc)) { + + case HG_ENCODE: + // find out the length of the context + ctx_length = *ctx ? sizeof(adm_adhoc_context) : 0; + ret = hg_proc_hg_size_t(proc, &ctx_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!ctx_length) { + return HG_SUCCESS; + } + + // if not NULL, write the context + tmp = *ctx; + ret = hg_proc_adm_adhoc_context(proc, &tmp); + + if(ret != HG_SUCCESS) { + break; + } + + break; + + case HG_DECODE: { + + // find out the length of the context + ret = hg_proc_hg_size_t(proc, &ctx_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!ctx_length) { + *ctx = NULL; + break; + } + + // if not NULL, read the context + tmp = (ADM_adhoc_context_t) calloc( + 1, sizeof(struct adm_adhoc_context)); + ret = hg_proc_adm_adhoc_context(proc, &tmp); + + if(ret != HG_SUCCESS) { + break; + } + + // return the newly-created ctx + *ctx = tmp; + break; + } + + case HG_FREE: + tmp = *ctx; + free(tmp); + ret = HG_SUCCESS; + break; + } + + return ret; +} diff --git a/src/lib/rpcs/public.hpp b/src/common/net/proto/rpc_types.h similarity index 65% rename from src/lib/rpcs/public.hpp rename to src/common/net/proto/rpc_types.h index 5e03eef0ba5afdf4a21eb94a37cd8a09c8faedd3..fcaf8cdd79e11a7b9e1473711cf640ec407a657c 100644 --- a/src/lib/rpcs/public.hpp +++ b/src/common/net/proto/rpc_types.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright 2021, Barcelona Supercomputing Center (BSC), Spain + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain * * This software was partially supported by the EuroHPC-funded project ADMIRE * (Project ID: 956748, https://www.admire-eurohpc.eu). @@ -22,100 +22,268 @@ * SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ -// clang-format off -#ifndef SCORD_RPCS_PUBLIC_HPP -#define SCORD_RPCS_PUBLIC_HPP +#ifndef SCORD_PROTO_TYPES_HPP +#define SCORD_PROTO_TYPES_HPP -#include -#include +#include // NOLINT #include #include -#include +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * N.B. MERCURY_GEN_STRUCT_PROC requires a `typedef` as its first argument, but + * admire_types.h also requires types to be defined as `struct T`s. Defining RPC + * types as `typedef struct T { ... } T;` solves both problems + */ + +typedef struct adm_node { + const char* n_hostname; +} adm_node; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_node, // NOLINT + ((hg_const_string_t) (n_hostname)) +); +// clang-format on + +typedef struct adm_dataset { + const char* d_id; +} adm_dataset; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_dataset, // NOLINT + ((hg_const_string_t) (d_id)) +); +// clang-format on + +typedef struct adm_job { + uint64_t j_id; +} adm_job; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_job, // NOLINT + ((hg_uint64_t) (j_id)) +); +// clang-format on + +struct adm_qos_entity { + ADM_qos_scope_t e_scope; + union { + ADM_node_t e_node; + ADM_job_t e_job; + ADM_dataset_t e_dataset; + ADM_transfer_t e_transfer; + }; +}; + +// TODO: encoder/decoder + +struct adm_qos_limit { + ADM_qos_entity_t l_entity; + ADM_qos_class_t l_class; + uint64_t l_value; +}; + +// TODO: encoder/decoder + +typedef struct adm_transfer { + // TODO: undefined for now + int32_t placeholder; +} adm_transfer; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_transfer, // NOLINT + ((hg_int32_t) (placeholder)) +); +// clang-format on + +typedef struct adm_dataset_info { + // TODO: undefined for now + int32_t placeholder; +} adm_dataset_info; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_dataset_info, // NOLINT + ((hg_int32_t) (placeholder)) +); +// clang-format on + +typedef struct adm_adhoc_context { + /** The adhoc storage system execution mode */ + ADM_adhoc_mode_t c_mode; + /** The adhoc storage system access type */ + ADM_adhoc_access_t c_access; + /** The number of nodes for the adhoc storage system */ + uint32_t c_nodes; + /** The adhoc storage system walltime */ + uint32_t c_walltime; + /** Whether the adhoc storage system should flush data in the background */ + bool c_should_bg_flush; +} adm_adhoc_context; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_adhoc_context, // NOLINT + ((hg_int32_t) (c_mode)) + ((hg_int32_t) (c_access)) + ((hg_uint32_t) (c_nodes)) + ((hg_uint32_t) (c_walltime)) + ((hg_bool_t) (c_should_bg_flush)) +) +// clang-format on + +typedef struct adm_pfs_context { + /** The PFS mount point */ + const char* c_mount; +} adm_pfs_context; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_pfs_context, // NOLINT + ((hg_const_string_t) (c_mount)) +); +// clang-format on + +typedef struct adm_storage { + const char* s_id; + ADM_storage_type_t s_type; + union { + adm_adhoc_context s_adhoc_ctx; + adm_pfs_context s_pfs_ctx; + }; +} adm_storage; + +hg_return_t +hg_proc_ADM_storage_t(hg_proc_t proc, void* data); + +typedef struct adm_storage_resources { + // TODO: undefined for now + int32_t placeholder; +} adm_storage_resources; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_storage_resources, // NOLINT + ((hg_int32_t) (placeholder)) +); +// clang-format on + +typedef struct adm_data_operation { + // TODO: undefined for now + int32_t placeholder; +} adm_data_operation; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_data_operation, // NOLINT + ((hg_int32_t) (placeholder)) +); +// clang-format on + + +struct adm_dataset_list { + /** An array of datasets */ + adm_dataset* l_datasets; + /** The length of the array */ + size_t l_length; +}; -// FIXME: cannot be in a namespace due to Margo limitations -// namespace scord::network::rpc { +hg_return_t +hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data); -/// ADM_ping -DECLARE_MARGO_RPC_HANDLER(ADM_ping); +hg_return_t +hg_proc_ADM_adhoc_context_t(hg_proc_t proc, void* data); + +hg_return_t +hg_proc_ADM_pfs_context_t(hg_proc_t proc, void* data); + + +/** The I/O requirements for a job */ +typedef struct adm_job_requirements { + /** An array of input datasets */ + ADM_dataset_list_t r_inputs; + /** An array of output datasets */ + ADM_dataset_list_t r_outputs; + /** An optional definition for a specific storage instance */ + ADM_storage_t r_storage; +} adm_job_requirements; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_job_requirements, // NOLINT + ((ADM_dataset_list_t) (r_inputs)) + ((ADM_dataset_list_t) (r_outputs)) + ((ADM_storage_t) (r_storage)) +); +// clang-format on + +// clang-format off /// ADM_register_job -MERCURY_GEN_PROC(ADM_register_job_in_t, ((int32_t) (reqs))) +MERCURY_GEN_PROC(ADM_register_job_in_t, ((adm_job_requirements) (reqs))) MERCURY_GEN_PROC(ADM_register_job_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_register_job); - /// ADM_update_job MERCURY_GEN_PROC(ADM_update_job_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_update_job_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_update_job); - /// ADM_remove_job MERCURY_GEN_PROC(ADM_remove_job_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_remove_job_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_remove_job); - /// ADM_register_adhoc_storage MERCURY_GEN_PROC(ADM_register_adhoc_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_register_adhoc_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_register_adhoc_storage); - /// ADM_update_adhoc_storage MERCURY_GEN_PROC(ADM_update_adhoc_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_update_adhoc_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_update_adhoc_storage); - /// ADM_remove_adhoc_storage MERCURY_GEN_PROC(ADM_remove_adhoc_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_remove_adhoc_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_remove_adhoc_storage); - /// ADM_deploy_adhoc_storage MERCURY_GEN_PROC(ADM_deploy_adhoc_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_deploy_adhoc_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_deploy_adhoc_storage); - /// ADM_register_pfs_storage MERCURY_GEN_PROC(ADM_register_pfs_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_register_pfs_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_register_pfs_storage); - /// ADM_update_pfs_storage MERCURY_GEN_PROC(ADM_update_pfs_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_update_pfs_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_update_pfs_storage); - /// ADM_remove_pfs_storage MERCURY_GEN_PROC(ADM_remove_pfs_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_remove_pfs_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_remove_pfs_storage); - /// ADM_input MERCURY_GEN_PROC(ADM_input_in_t, ((hg_const_string_t) (origin))((hg_const_string_t) (target))) MERCURY_GEN_PROC(ADM_input_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_input); - /// ADM_output MERCURY_GEN_PROC(ADM_output_in_t, @@ -123,8 +291,6 @@ MERCURY_GEN_PROC(ADM_output_in_t, MERCURY_GEN_PROC(ADM_output_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_output); - /// ADM_inout MERCURY_GEN_PROC(ADM_inout_in_t, @@ -132,8 +298,6 @@ MERCURY_GEN_PROC(ADM_inout_in_t, MERCURY_GEN_PROC(ADM_inout_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_inout); - /// ADM_adhoc_context MERCURY_GEN_PROC(ADM_adhoc_context_in_t, ((hg_const_string_t) (context))) @@ -141,32 +305,24 @@ MERCURY_GEN_PROC(ADM_adhoc_context_in_t, ((hg_const_string_t) (context))) MERCURY_GEN_PROC(ADM_adhoc_context_out_t, ((int32_t) (ret))((int32_t) (adhoc_context))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_context); - /// ADM_adhoc_context_id MERCURY_GEN_PROC(ADM_adhoc_context_id_in_t, ((int32_t) (context_id))) MERCURY_GEN_PROC(ADM_adhoc_context_id_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_context_id); - /// ADM_adhoc_nodes MERCURY_GEN_PROC(ADM_adhoc_nodes_in_t, ((int32_t) (nodes))) MERCURY_GEN_PROC(ADM_adhoc_nodes_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_nodes) - /// ADM_adhoc_walltime MERCURY_GEN_PROC(ADM_adhoc_walltime_in_t, ((int32_t) (walltime))) MERCURY_GEN_PROC(ADM_adhoc_walltime_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_walltime); - /// ADM_adhoc_access @@ -174,8 +330,6 @@ MERCURY_GEN_PROC(ADM_adhoc_access_in_t, ((hg_const_string_t) (access))) MERCURY_GEN_PROC(ADM_adhoc_access_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_access); - /// ADM_adhoc_distribution MERCURY_GEN_PROC(ADM_adhoc_distribution_in_t, @@ -183,32 +337,24 @@ MERCURY_GEN_PROC(ADM_adhoc_distribution_in_t, MERCURY_GEN_PROC(ADM_adhoc_distribution_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_distribution); - /// ADM_adhoc_background_flush MERCURY_GEN_PROC(ADM_adhoc_background_flush_in_t, ((hg_bool_t) (b_flush))) MERCURY_GEN_PROC(ADM_adhoc_background_flush_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_background_flush); - /// ADM_in_situ_ops MERCURY_GEN_PROC(ADM_in_situ_ops_in_t, ((hg_const_string_t) (in_situ))) MERCURY_GEN_PROC(ADM_in_situ_ops_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_in_situ_ops); - /// ADM_in_transit_ops MERCURY_GEN_PROC(ADM_in_transit_ops_in_t, ((hg_const_string_t) (in_transit))) MERCURY_GEN_PROC(ADM_in_transit_ops_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_in_transit_ops); - /// ADM_transfer_dataset @@ -221,8 +367,6 @@ MERCURY_GEN_PROC( MERCURY_GEN_PROC(ADM_transfer_dataset_out_t, ((int32_t) (ret))((hg_const_string_t) (transfer_handle))) -DECLARE_MARGO_RPC_HANDLER(ADM_transfer_dataset); - /// ADM_set_dataset_information MERCURY_GEN_PROC(ADM_set_dataset_information_in_t, @@ -232,8 +376,6 @@ MERCURY_GEN_PROC(ADM_set_dataset_information_in_t, MERCURY_GEN_PROC(ADM_set_dataset_information_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_set_dataset_information); - /// ADM_set_io_resources MERCURY_GEN_PROC(ADM_set_io_resources_in_t, @@ -243,8 +385,6 @@ MERCURY_GEN_PROC(ADM_set_io_resources_in_t, MERCURY_GEN_PROC(ADM_set_io_resources_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_set_io_resources); - /// ADM_get_transfer_priority MERCURY_GEN_PROC(ADM_get_transfer_priority_in_t, ((int32_t) (transfer_id))) @@ -252,8 +392,6 @@ MERCURY_GEN_PROC(ADM_get_transfer_priority_in_t, ((int32_t) (transfer_id))) MERCURY_GEN_PROC(ADM_get_transfer_priority_out_t, ((int32_t) (ret))((int32_t) (priority))) -DECLARE_MARGO_RPC_HANDLER(ADM_get_transfer_priority); - /// ADM_set_transfer_priority MERCURY_GEN_PROC(ADM_set_transfer_priority_in_t, @@ -262,8 +400,6 @@ MERCURY_GEN_PROC(ADM_set_transfer_priority_in_t, MERCURY_GEN_PROC(ADM_set_transfer_priority_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_set_transfer_priority); - /// ADM_cancel_transfer MERCURY_GEN_PROC(ADM_cancel_transfer_in_t, ((int32_t) (transfer_id))) @@ -271,8 +407,6 @@ MERCURY_GEN_PROC(ADM_cancel_transfer_in_t, ((int32_t) (transfer_id))) MERCURY_GEN_PROC(ADM_cancel_transfer_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_cancel_transfer); - /// ADM_get_pending_transfers MERCURY_GEN_PROC(ADM_get_pending_transfers_in_t, ((hg_const_string_t) (value))) @@ -280,8 +414,6 @@ MERCURY_GEN_PROC(ADM_get_pending_transfers_in_t, ((hg_const_string_t) (value))) MERCURY_GEN_PROC(ADM_get_pending_transfers_out_t, ((int32_t) (ret))((hg_const_string_t) (pending_transfers))) -DECLARE_MARGO_RPC_HANDLER(ADM_get_pending_transfers); - /// ADM_set_qos_constraints MERCURY_GEN_PROC( @@ -292,8 +424,6 @@ MERCURY_GEN_PROC( MERCURY_GEN_PROC(ADM_set_qos_constraints_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_set_qos_constraints); - /// ADM_get_qos_constraints MERCURY_GEN_PROC(ADM_get_qos_constraints_in_t, @@ -302,8 +432,6 @@ MERCURY_GEN_PROC(ADM_get_qos_constraints_in_t, MERCURY_GEN_PROC(ADM_get_qos_constraints_out_t, ((int32_t) (ret))((hg_const_string_t) (list))) -DECLARE_MARGO_RPC_HANDLER(ADM_get_qos_constraints); - /// ADM_define_data_operation MERCURY_GEN_PROC(ADM_define_data_operation_in_t, @@ -313,8 +441,6 @@ MERCURY_GEN_PROC(ADM_define_data_operation_in_t, MERCURY_GEN_PROC(ADM_define_data_operation_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_define_data_operation); - /// ADM_connect_data_operation MERCURY_GEN_PROC(ADM_connect_data_operation_in_t, @@ -326,8 +452,6 @@ MERCURY_GEN_PROC(ADM_connect_data_operation_out_t, ((int32_t) (ret))((hg_const_string_t) (data))( (hg_const_string_t) (operation_handle))) -DECLARE_MARGO_RPC_HANDLER(ADM_connect_data_operation); - /// ADM_finalize_data_operation MERCURY_GEN_PROC(ADM_finalize_data_operation_in_t, ((int32_t) (operation_id))) @@ -336,8 +460,6 @@ MERCURY_GEN_PROC(ADM_finalize_data_operation_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_finalize_data_operation); - /// ADM_link_transfer_to_data_operation MERCURY_GEN_PROC(ADM_link_transfer_to_data_operation_in_t, @@ -348,8 +470,6 @@ MERCURY_GEN_PROC(ADM_link_transfer_to_data_operation_in_t, MERCURY_GEN_PROC(ADM_link_transfer_to_data_operation_out_t, ((int32_t) (ret))((hg_const_string_t) (operation_handle))) -DECLARE_MARGO_RPC_HANDLER(ADM_link_transfer_to_data_operation); - /// ADM_get_statistics MERCURY_GEN_PROC(ADM_get_statistics_in_t, @@ -358,10 +478,10 @@ MERCURY_GEN_PROC(ADM_get_statistics_in_t, MERCURY_GEN_PROC(ADM_get_statistics_out_t, ((int32_t) (ret))((hg_const_string_t) (job_statistics))) -DECLARE_MARGO_RPC_HANDLER(ADM_get_statistics); - +// clang-format on -//} // namespace scord::network::rpc +#ifdef __cplusplus +}; // extern "C" +#endif // __cplusplus -#endif // SCORD_RPCS_PUBLIC_HPP -// clang-format on +#endif // SCORD_PROTO_TYPES_HPP diff --git a/src/common/network/server.cpp b/src/common/net/server.cpp similarity index 100% rename from src/common/network/server.cpp rename to src/common/net/server.cpp diff --git a/src/common/network/server.hpp b/src/common/net/server.hpp similarity index 100% rename from src/common/network/server.hpp rename to src/common/net/server.hpp diff --git a/src/common/utils/CMakeLists.txt b/src/common/utils/CMakeLists.txt index 576d08a1e36108f10cdcbf95288bd2b486ccb203..6f35c65821aeb039ee1ad537be0aa6c91e6a4047 100644 --- a/src/common/utils/CMakeLists.txt +++ b/src/common/utils/CMakeLists.txt @@ -26,4 +26,4 @@ add_library(_utils STATIC) set_property(TARGET _utils PROPERTY POSITION_INDEPENDENT_CODE ON) -target_sources(_utils PRIVATE utils.hpp utils.cpp signal_listener.hpp) +target_sources(_utils PRIVATE utils.hpp utils.cpp signal_listener.hpp c_ptr.hpp) diff --git a/src/common/utils/c_ptr.hpp b/src/common/utils/c_ptr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..51de8d82fd306aa8730de6bacd9e4af2e97ea131 --- /dev/null +++ b/src/common/utils/c_ptr.hpp @@ -0,0 +1,94 @@ +/****************************************************************************** + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + + +#ifndef SCORD_UTILS_C_PTR_HPP +#define SCORD_UTILS_C_PTR_HPP + +#include +#include + +namespace scord::utils { + +// A manager for a C raw pointer. It allows to automatically delete dynamically +// allocated C structs in a RAII manner (provided that there is a deleter +// function for the struct available). +template +struct deleter { + void + operator()(T* ptr) { + fn(ptr); + } +}; + +template +using c_ptr = std::unique_ptr>; + +// A manager for a vector of C raw pointers. It allows to automatically +// delete the dynamically allocated C structs pointed by each vector elements +// in a RAII manner (provided that there is a deleter function for the struct +// available). Can also be used to directly pass an array of C pointers to C +// APIs by means of the data() function. +template +struct c_ptr_vector { + + c_ptr_vector() = default; + + ~c_ptr_vector() = default; + + constexpr void + reserve(size_t n) { + m_data.reserve(n); + m_addrs.reserve(n); + } + + template + constexpr void + emplace_back(Args&&... args) { + const auto& tmp = m_data.emplace_back(args...); + m_addrs.push_back(tmp.get()); + } + + constexpr const T* const* + data() const noexcept { + return m_addrs.data(); + } + + constexpr T** + data() noexcept { + return m_addrs.data(); + } + + constexpr std::size_t + size() const noexcept { + return m_data.size(); + } + + std::vector> m_data{}; + std::vector m_addrs{}; +}; + +} // namespace scord::utils + +#endif // SCORD_UTILS_C_PTR_HPP diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 4ef754f0acab893b40869697e739fdcbb4bcc57b..7d7cbeef468eaa5a48de1534c63e0a79bb3b369c 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -22,25 +22,27 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ -# target for the public rpcs defined by the API that need to be shared by scord -add_library(api_rpcs STATIC) -target_sources(api_rpcs - PRIVATE rpcs/public.cpp rpcs/public.hpp) +add_library(admire_types STATIC) -target_include_directories(api_rpcs INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/rpcs) -target_link_libraries(api_rpcs PUBLIC common::logger Margo::Margo) -set_property(TARGET api_rpcs PROPERTY POSITION_INDEPENDENT_CODE ON) +target_sources(admire_types PUBLIC admire_types.h admire_types.hpp PRIVATE + types.cpp) + +target_link_libraries(admire_types PRIVATE common::network::rpc_types + Margo::Margo common::logger) + +set_target_properties(admire_types PROPERTIES POSITION_INDEPENDENT_CODE ON) # the client library implementing the actual API add_library(adm_iosched SHARED) target_sources(adm_iosched - PUBLIC admire.h types.h admire.hpp + PUBLIC admire.h admire_types.h admire.hpp admire_types.hpp PRIVATE admire.cpp c_wrapper.cpp detail/impl.hpp detail/impl.cpp errors.c) target_include_directories(adm_iosched PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(adm_iosched PRIVATE common::network::engine api_rpcs PUBLIC +target_link_libraries(adm_iosched PRIVATE common::network::engine + common::network::rpc_types admire_types PUBLIC tl::expected) install( diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index 6c42295b1aaf80b7ab306cfc4f7ee8685dc59678..6bc8aa16dee28f6f5d3eb0f6a2b92df16a1113fe 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -23,9 +23,10 @@ *****************************************************************************/ #include -#include +#include +#include #include -#include "rpcs/public.hpp" +#include #include "detail/impl.hpp" @@ -52,124 +53,118 @@ init_logger() { void rpc_registration_cb(scord::network::rpc_client* client) { - REGISTER_RPC(client, "ADM_ping", void, void, ADM_ping, false); + REGISTER_RPC(client, "ADM_ping", void, void, NULL, false); REGISTER_RPC(client, "ADM_register_job", ADM_register_job_in_t, - ADM_register_job_out_t, ADM_register_job, true); + ADM_register_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_update_job", ADM_update_job_in_t, - ADM_update_job_out_t, ADM_update_job, true); + ADM_update_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_remove_job", ADM_remove_job_in_t, - ADM_remove_job_out_t, ADM_remove_job, true); + ADM_remove_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_register_adhoc_storage", ADM_register_adhoc_storage_in_t, - ADM_register_adhoc_storage_out_t, ADM_register_adhoc_storage, - true); + ADM_register_adhoc_storage_out_t, NULL, true); REGISTER_RPC(client, "ADM_update_adhoc_storage", ADM_update_adhoc_storage_in_t, ADM_update_adhoc_storage_out_t, - ADM_update_adhoc_storage, true); + NULL, true); REGISTER_RPC(client, "ADM_remove_adhoc_storage", ADM_remove_adhoc_storage_in_t, ADM_remove_adhoc_storage_out_t, - ADM_remove_adhoc_storage, true); + NULL, true); REGISTER_RPC(client, "ADM_deploy_adhoc_storage", ADM_deploy_adhoc_storage_in_t, ADM_deploy_adhoc_storage_out_t, - ADM_deploy_adhoc_storage, true); + NULL, true); - REGISTER_RPC(client, "ADM_input", ADM_input_in_t, ADM_input_out_t, - ADM_input, true); + REGISTER_RPC(client, "ADM_input", ADM_input_in_t, ADM_input_out_t, NULL, + true); - REGISTER_RPC(client, "ADM_output", ADM_output_in_t, ADM_output_out_t, - ADM_output, true); + REGISTER_RPC(client, "ADM_output", ADM_output_in_t, ADM_output_out_t, NULL, + true); - REGISTER_RPC(client, "ADM_inout", ADM_inout_in_t, ADM_inout_out_t, - ADM_inout, true); + REGISTER_RPC(client, "ADM_inout", ADM_inout_in_t, ADM_inout_out_t, NULL, + true); REGISTER_RPC(client, "ADM_adhoc_context", ADM_adhoc_context_in_t, - ADM_adhoc_context_out_t, ADM_adhoc_context, true); + ADM_adhoc_context_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_context_id", ADM_adhoc_context_id_in_t, - ADM_adhoc_context_id_out_t, ADM_adhoc_context_id, true); + ADM_adhoc_context_id_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_nodes", ADM_adhoc_nodes_in_t, - ADM_adhoc_nodes_out_t, ADM_adhoc_nodes, true); + ADM_adhoc_nodes_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_walltime", ADM_adhoc_walltime_in_t, - ADM_adhoc_walltime_out_t, ADM_adhoc_walltime, true); + ADM_adhoc_walltime_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_access", ADM_adhoc_access_in_t, - ADM_adhoc_access_out_t, ADM_adhoc_access, true); + ADM_adhoc_access_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_distribution", ADM_adhoc_distribution_in_t, - ADM_adhoc_distribution_out_t, ADM_adhoc_distribution, true); + ADM_adhoc_distribution_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_background_flush", ADM_adhoc_background_flush_in_t, - ADM_adhoc_background_flush_out_t, ADM_adhoc_background_flush, - true); + ADM_adhoc_background_flush_out_t, NULL, true); REGISTER_RPC(client, "ADM_in_situ_ops", ADM_in_situ_ops_in_t, - ADM_in_situ_ops_out_t, ADM_in_situ_ops, true); + ADM_in_situ_ops_out_t, NULL, true); REGISTER_RPC(client, "ADM_in_transit_ops", ADM_in_transit_ops_in_t, - ADM_in_transit_ops_out_t, ADM_in_transit_ops, true); + ADM_in_transit_ops_out_t, NULL, true); REGISTER_RPC(client, "ADM_transfer_dataset", ADM_transfer_dataset_in_t, - ADM_transfer_dataset_out_t, ADM_transfer_dataset, true); + ADM_transfer_dataset_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_dataset_information", ADM_set_dataset_information_in_t, - ADM_set_dataset_information_out_t, ADM_set_dataset_information, - true); + ADM_set_dataset_information_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_io_resources", ADM_set_io_resources_in_t, - ADM_set_io_resources_out_t, ADM_set_io_resources, true); + ADM_set_io_resources_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_get_transfer_priority", ADM_get_transfer_priority_in_t, - ADM_get_transfer_priority_out_t, ADM_get_transfer_priority, true); + REGISTER_RPC(client, "ADM_get_transfer_priority", + ADM_get_transfer_priority_in_t, + ADM_get_transfer_priority_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_set_transfer_priority", ADM_set_transfer_priority_in_t, - ADM_set_transfer_priority_out_t, ADM_set_transfer_priority, true); + REGISTER_RPC(client, "ADM_set_transfer_priority", + ADM_set_transfer_priority_in_t, + ADM_set_transfer_priority_out_t, NULL, true); REGISTER_RPC(client, "ADM_cancel_transfer", ADM_cancel_transfer_in_t, - ADM_cancel_transfer_out_t, ADM_cancel_transfer, true); + ADM_cancel_transfer_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_get_pending_transfers", ADM_get_pending_transfers_in_t, - ADM_get_pending_transfers_out_t, ADM_get_pending_transfers, true); + REGISTER_RPC(client, "ADM_get_pending_transfers", + ADM_get_pending_transfers_in_t, + ADM_get_pending_transfers_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_qos_constraints", ADM_set_qos_constraints_in_t, ADM_set_qos_constraints_out_t, - ADM_set_qos_constraints, true); + NULL, true); REGISTER_RPC(client, "ADM_get_qos_constraints", ADM_get_qos_constraints_in_t, ADM_get_qos_constraints_out_t, - ADM_get_qos_constraints, true); + NULL, true); - REGISTER_RPC( - client, "ADM_define_data_operation", ADM_define_data_operation_in_t, - ADM_define_data_operation_out_t, ADM_define_data_operation, true); + REGISTER_RPC(client, "ADM_define_data_operation", + ADM_define_data_operation_in_t, + ADM_define_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_connect_data_operation", ADM_connect_data_operation_in_t, - ADM_connect_data_operation_out_t, ADM_connect_data_operation, - true); + ADM_connect_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_finalize_data_operation", ADM_finalize_data_operation_in_t, - ADM_finalize_data_operation_out_t, ADM_finalize_data_operation, - true); + ADM_finalize_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_link_transfer_to_data_operation", ADM_link_transfer_to_data_operation_in_t, - ADM_link_transfer_to_data_operation_out_t, - ADM_link_transfer_to_data_operation, true); + ADM_link_transfer_to_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_get_statistics", ADM_get_statistics_in_t, - ADM_get_statistics_out_t, ADM_get_statistics, true); + ADM_get_statistics_out_t, NULL, true); } } // namespace @@ -188,7 +183,7 @@ ping(const server& srv) { admire::job -register_job(const server& srv, ADM_job_requirements_t reqs) { +register_job(const server& srv, const job_requirements& reqs) { const auto rv = detail::register_job(srv, reqs); @@ -200,83 +195,43 @@ register_job(const server& srv, ADM_job_requirements_t reqs) { return rv.value(); } -ADM_return_t -update_job(const server& srv, ADM_job_t job, ADM_job_requirements_t reqs) { - (void) srv; - (void) job; - (void) reqs; - - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; - - auto endp = rpc_client.lookup(srv.m_address); - - LOGGER_INFO("ADM_update_job(...)"); - - ADM_update_job_in_t in{}; - ADM_update_job_out_t out; +admire::job +update_job(const server& srv, const job& job, const job_requirements& reqs) { - endp.call("ADM_update_job", &in, &out); + const auto rv = detail::update_job(srv, job, reqs); - if(out.ret < 0) { - LOGGER_ERROR("ADM_update_job() = {}", out.ret); - return static_cast(out.ret); + if(!rv) { + throw std::runtime_error(fmt::format("ADM_update_job() error: {}", + ADM_strerror(rv.error()))); } - LOGGER_INFO("ADM_update_job() = {}", ADM_SUCCESS); - return ADM_SUCCESS; + return rv.value(); } -ADM_return_t -remove_job(const server& srv, ADM_job_t job) { - (void) srv; - (void) job; - - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; - - auto endp = rpc_client.lookup(srv.m_address); - - LOGGER_INFO("ADM_remove_job(...)"); - - ADM_remove_job_in_t in{}; - ADM_remove_job_out_t out; +admire::job +remove_job(const server& srv, const job& job) { - endp.call("ADM_remove_job", &in, &out); + const auto rv = detail::remove_job(srv, job); - if(out.ret < 0) { - LOGGER_ERROR("ADM_remove_job() = {}", out.ret); - return static_cast(out.ret); + if(!rv) { + throw std::runtime_error(fmt::format("ADM_remove_job() error: {}", + ADM_strerror(rv.error()))); } - LOGGER_INFO("ADM_remove_job() = {}", ADM_SUCCESS); - return ADM_SUCCESS; + return rv.value(); } -ADM_return_t -register_adhoc_storage(const server& srv, ADM_job_t job, - ADM_adhoc_context_t ctx, ADM_storage_t* adhoc_storage) { - (void) srv; - (void) job; - (void) ctx; - (void) adhoc_storage; - - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; - - auto endp = rpc_client.lookup(srv.m_address); - - LOGGER_INFO("ADM_register_adhoc_storage(...)"); - - ADM_register_adhoc_storage_in_t in{}; - ADM_register_adhoc_storage_out_t out; +admire::adhoc_storage +register_adhoc_storage(const server& srv, const job& job, + const adhoc_storage::context& ctx) { + const auto rv = detail::register_adhoc_storage(srv, job, ctx); - endp.call("ADM_register_adhoc_storage", &in, &out); - - if(out.ret < 0) { - LOGGER_ERROR("ADM_register_adhoc_storage() = {}", out.ret); - return static_cast(out.ret); + if(!rv) { + throw std::runtime_error(fmt::format("ADM_register_adhoc_storage() error: {}", + ADM_strerror(rv.error()))); } - LOGGER_INFO("ADM_register_adhoc_storage() = {}", ADM_SUCCESS); - return ADM_SUCCESS; + return rv.value(); } ADM_return_t diff --git a/src/lib/admire.h b/src/lib/admire.h index fa43160211c5369b3d64a85f8b1a750668c81cf8..9a67b4491c3fed06a58567307470328198679885 100644 --- a/src/lib/admire.h +++ b/src/lib/admire.h @@ -28,7 +28,7 @@ #include #include #include -#include "types.h" +#include "admire_types.h" #ifdef __cplusplus extern "C" { @@ -44,7 +44,7 @@ extern "C" { /* Public type definitions and type-related functions */ /******************************************************************************/ -// See types.h +// See admire_types.h /******************************************************************************/ diff --git a/src/lib/admire.hpp b/src/lib/admire.hpp index 9f58a953b992422dbfe51fee6b40d64d6930d9f4..2bf01e808ebcda34405ef7ce3235966e2bd563d3 100644 --- a/src/lib/admire.hpp +++ b/src/lib/admire.hpp @@ -23,39 +23,40 @@ *****************************************************************************/ #include -#include -#include #include +#include +#include "admire_types.hpp" +#include "net/proto/rpc_types.h" #ifndef SCORD_ADMIRE_HPP #define SCORD_ADMIRE_HPP -namespace admire { +/******************************************************************************/ +/* Public type definitions and type-related functions */ +/******************************************************************************/ + +// See admire_types.hpp -using job_id = int64_t; -struct server { - std::string m_protocol; - std::string m_address; -}; +/******************************************************************************/ +/* Public prototypes */ +/******************************************************************************/ -struct job { - job_id m_id; -}; +namespace admire { void ping(const server& srv); admire::job -register_job(const server& srv, ADM_job_requirements_t reqs); +register_job(const server& srv, const job_requirements& reqs); -ADM_return_t -update_job(const server& srv, ADM_job_t job, ADM_job_requirements_t reqs); +admire::job +update_job(const server& srv, const job&, const job_requirements& reqs); -ADM_return_t -remove_job(const server& srv, ADM_job_t job); +admire::job +remove_job(const server& srv, const job& job); -ADM_return_t +admire::adhoc_storage register_adhoc_storage(const server& srv, ADM_job_t job, ADM_adhoc_context_t ctx, ADM_storage_t* adhoc_storage); diff --git a/src/lib/types.h b/src/lib/admire_types.h similarity index 94% rename from src/lib/types.h rename to src/lib/admire_types.h index 4ff80dc833ebd0422789878b7640642068644a1b..13b43bfec1f4407f892c9518bed36c57cf50c516 100644 --- a/src/lib/types.h +++ b/src/lib/admire_types.h @@ -22,8 +22,13 @@ * SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ -#ifndef SCORD_TYPES_H -#define SCORD_TYPES_H +#ifndef SCORD_ADMIRE_TYPES_H +#define SCORD_ADMIRE_TYPES_H + +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -83,6 +88,9 @@ typedef struct adm_dataset* ADM_dataset_t; /** Information about a dataset */ typedef struct adm_dataset_info* ADM_dataset_info_t; +/** A list of datasets */ +typedef struct adm_dataset_list* ADM_dataset_list_t; + /* ----------------------------------------------------- */ /* Storage tiers */ @@ -314,6 +322,29 @@ ADM_dataset_info_create(); ADM_return_t ADM_dataset_info_destroy(ADM_dataset_info_t dataset_info); +/** + * Create a dataset list from an array of ADM_DATASETs and its + * length. + * + * @remark Dataset lists need to be freed by calling ADM_dataset_list_destroy(). + * + * @param[in] datasets The array of datasets. + * @param[in] len The length of the array. + * @return A valid ADM_dataset_list_t if successful or NULL in case of + * failure. + */ +ADM_dataset_list_t +ADM_dataset_list_create(ADM_dataset_t datasets[], size_t len); + +/** + * Destroy a dataset list created by ADM_dataset_list_create(). + * + * @param[in] list A valid ADM_dataset_list_t + * @return ADM_SUCCESS or corresponding ADM error code + */ +ADM_return_t +ADM_dataset_list_destroy(ADM_dataset_list_t list); + /* ----------------------------------------------------- */ /* Storage tiers */ @@ -495,4 +526,4 @@ ADM_data_operation_destroy(ADM_data_operation_t op); } // extern "C" #endif -#endif // SCORD_TYPES_H +#endif // SCORD_ADMIRE_TYPES_H diff --git a/src/lib/admire_types.hpp b/src/lib/admire_types.hpp new file mode 100644 index 0000000000000000000000000000000000000000..28f9930a2e5e575abe4e902af34f717d20943e31 --- /dev/null +++ b/src/lib/admire_types.hpp @@ -0,0 +1,397 @@ +/****************************************************************************** + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + +#ifndef SCORD_ADMIRE_TYPES_HPP +#define SCORD_ADMIRE_TYPES_HPP + +#include +#include +#include +#include +#include +#include "admire_types.h" + +namespace admire { + +using job_id = std::int64_t; + +struct server { + + server(std::string protocol, std::string address); + + explicit server(const ADM_server_t& srv); + + std::string m_protocol; + std::string m_address; +}; + +struct job { + + explicit job(job_id id); + + explicit job(ADM_job_t job); + + [[nodiscard]] ADM_job_t + to_ctype() const; + + job_id m_id; +}; + +struct dataset { + explicit dataset(std::string id) : m_id(std::move(id)) {} + + std::string + to_string() const { + return "foo"; + } + + std::string m_id; +}; + +struct storage { + + enum class type : std::underlying_type::type { + gekkofs = ADM_STORAGE_GEKKOFS, + dataclay = ADM_STORAGE_DATACLAY, + expand = ADM_STORAGE_EXPAND, + hercules = ADM_STORAGE_HERCULES, + lustre = ADM_STORAGE_LUSTRE, + gpfs = ADM_STORAGE_GPFS + }; + + storage(storage::type type, std::string id); + + virtual ~storage() = default; + + virtual ADM_storage_t + to_rpc_type() const = 0; + + std::string m_id; + type m_type; +}; + +struct adhoc_storage : public storage { + + enum class execution_mode : std::underlying_type::type { + in_job_shared = ADM_ADHOC_MODE_IN_JOB_SHARED, + in_job_dedicated = ADM_ADHOC_MODE_IN_JOB_DEDICATED, + separate_new = ADM_ADHOC_MODE_SEPARATE_NEW, + separate_existing = ADM_ADHOC_MODE_SEPARATE_EXISTING + }; + + enum class access_type : std::underlying_type::type { + read_only = ADM_ADHOC_ACCESS_RDONLY, + write_only = ADM_ADHOC_ACCESS_WRONLY, + read_write = ADM_ADHOC_ACCESS_RDWR, + }; + + struct context { + + context(execution_mode exec_mode, access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, bool should_flush); + + explicit context(ADM_adhoc_context_t ctx); + + ADM_adhoc_context_t + to_rpc_type() const; + + execution_mode m_exec_mode; + access_type m_access_type; + std::uint32_t m_nodes; + std::uint32_t m_walltime; + bool m_should_flush; + }; + + adhoc_storage(storage::type type, std::string id, execution_mode exec_mode, + access_type access_type, std::uint32_t nodes, + std::uint32_t walltime, bool should_flush); + + adhoc_storage(storage::type type, std::string id, ADM_adhoc_context_t ctx); + + + ADM_storage_t + to_rpc_type() const final; + + context m_ctx; +}; + +struct pfs_storage : public storage { + + struct context { + + explicit context(std::filesystem::path mount_point); + + explicit context(ADM_pfs_context_t ctx); + + ADM_pfs_context_t + to_rpc_type() const; + + std::filesystem::path m_mount_point; + }; + + pfs_storage(storage::type type, std::string id, + std::filesystem::path mount_point); + + pfs_storage(storage::type type, std::string id, ADM_pfs_context_t ctx); + + ADM_storage_t + to_rpc_type() const final; + + context m_ctx; +}; + +struct job_requirements { + + job_requirements(std::vector inputs, + std::vector outputs); + + job_requirements(std::vector inputs, + std::vector outputs, + std::unique_ptr storage); + + explicit job_requirements(ADM_job_requirements_t reqs); + + ADM_job_requirements_t + to_rpc_type() const; + + std::vector m_inputs; + std::vector m_outputs; + std::unique_ptr m_storage; +}; + +} // namespace admire + + +//////////////////////////////////////////////////////////////////////////////// +// Formatting functions +//////////////////////////////////////////////////////////////////////////////// + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::dataset& d, FormatContext& ctx) const { + return formatter::format("\"" + d.m_id + "\"", ctx); + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::storage::type& t, FormatContext& ctx) const { + + using admire::storage; + std::string_view name = "unknown"; + + switch(t) { + case storage::type::gekkofs: + name = "ADM_STORAGE_GEKKOFS"; + break; + case storage::type::dataclay: + name = "ADM_STORAGE_DATACLAY"; + break; + case storage::type::expand: + name = "ADM_STORAGE_EXPAND"; + break; + case storage::type::hercules: + name = "ADM_STORAGE_HERCULES"; + break; + case storage::type::lustre: + name = "ADM_STORAGE_LUSTRE"; + break; + case storage::type::gpfs: + name = "ADM_STORAGE_GPFS"; + break; + } + + return formatter::format(name, ctx); + } +}; + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::adhoc_storage::execution_mode& exec_mode, + FormatContext& ctx) const { + + using execution_mode = admire::adhoc_storage::execution_mode; + + std::string_view name = "unknown"; + + switch(exec_mode) { + case execution_mode::in_job_shared: + name = "IN_JOB_SHARED"; + break; + case execution_mode::in_job_dedicated: + name = "IN_JOB_DEDICATED"; + break; + case execution_mode::separate_new: + name = "SEPARATE_NEW"; + break; + case execution_mode::separate_existing: + name = "SEPARATE_EXISTING"; + break; + } + + return formatter::format(name, ctx); + } +}; + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::adhoc_storage::access_type& type, + FormatContext& ctx) const { + + using access_type = admire::adhoc_storage::access_type; + + std::string_view name = "unknown"; + + switch(type) { + case access_type::read_only: + name = "RDONLY"; + break; + case access_type::write_only: + name = "WRONLY"; + break; + case access_type::read_write: + name = "RDWR"; + break; + } + + return formatter::format(name, ctx); + } +}; + +template <> +struct fmt::formatter> + : formatter { + // parse is inherited from formatter. + template + auto + format(const std::unique_ptr& s, + FormatContext& ctx) const { + + switch(s->m_type) { + case admire::storage::type::gekkofs: + case admire::storage::type::dataclay: + case admire::storage::type::expand: + case admire::storage::type::hercules: + return formatter::format( + fmt::format("{}", + *(dynamic_cast( + s.get()))), + ctx); + case admire::storage::type::lustre: + case admire::storage::type::gpfs: + return formatter::format( + fmt::format("{}", *(dynamic_cast( + s.get()))), + ctx); + default: + return formatter::format("unknown", ctx); + } + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::adhoc_storage& s, FormatContext& ctx) const { + const auto str = fmt::format("{{type: {}, id: {}, context: {}}}", + s.m_type, std::quoted(s.m_id), s.m_ctx); + return formatter::format(str, ctx); + } +}; + + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::adhoc_storage::context& c, FormatContext& ctx) const { + + const auto str = + fmt::format("{{execution_mode: {}, access_type: {}, " + "nodes: {}, walltime: {}, should_flush: {}}}", + c.m_exec_mode, c.m_access_type, c.m_nodes, + c.m_walltime, c.m_should_flush); + + return formatter::format(str, ctx); + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::pfs_storage& s, FormatContext& ctx) const { + const auto str = fmt::format("{{m_ctx: {}}}", s.m_ctx); + return formatter::format(str, ctx); + } +}; + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::pfs_storage::context& c, FormatContext& ctx) const { + const auto str = fmt::format("{{mount_point: {}}}", c.m_mount_point); + return formatter::format(str, ctx); + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::job_requirements& r, FormatContext& ctx) const { + return formatter::format( + fmt::format("inputs: [{}], outputs: [{}], storage: {}", + fmt::join(r.m_inputs, ", "), + fmt::join(r.m_outputs, ", "), + (r.m_storage ? fmt::format("{}", r.m_storage) + : "NULL")), + ctx); + } +}; + +#endif // SCORD_ADMIRE_TYPES_HPP diff --git a/src/lib/c_wrapper.cpp b/src/lib/c_wrapper.cpp index 6cf1747f4428da23c289833158b361bdd25c1d85..1ef0ed6992b99c4eda6c1c6a771594ebfb623bf5 100644 --- a/src/lib/c_wrapper.cpp +++ b/src/lib/c_wrapper.cpp @@ -25,555 +25,19 @@ #include #include #include +#include +#include +#include "admire_types.hpp" +#include "admire_types.h" #include "detail/impl.hpp" -/******************************************************************************/ -/* Type definitions and related functions */ -/******************************************************************************/ - -struct adm_server { - const char* s_protocol; - const char* s_address; -}; - -struct adm_node { - const char* n_hostname; -}; - -struct adm_dataset { - const char* d_id; -}; - -struct adm_job { - uint64_t j_id; -}; - -struct adm_qos_entity { - ADM_qos_scope_t e_scope; - union { - ADM_node_t e_node; - ADM_job_t e_job; - ADM_dataset_t e_dataset; - ADM_transfer_t e_transfer; - }; -}; - -struct adm_qos_limit { - ADM_qos_entity_t l_entity; - ADM_qos_class_t l_class; - uint64_t l_value; -}; - -struct adm_transfer { - // TODO: empty for now -}; - -struct adm_dataset_info { - // TODO: empty for now -}; - -struct adm_storage { - const char* s_id; - ADM_storage_type_t s_type; - union { - ADM_adhoc_context_t s_adhoc_ctx; - ADM_pfs_context_t s_pfs_ctx; - }; -}; - -struct adm_storage_resources { - // TODO: empty for now -}; - -struct adm_data_operation { - // TODO: empty for now -}; - -struct adm_adhoc_context { - /** The adhoc storage system execution mode */ - ADM_adhoc_mode_t c_mode; - /** The adhoc storage system access type */ - ADM_adhoc_access_t c_access; - /** The number of nodes for the adhoc storage system */ - uint32_t c_nodes; - /** The adhoc storage system walltime */ - uint32_t c_walltime; - /** Whether the adhoc storage system should flush data in the background */ - bool c_should_bg_flush; -}; - -struct adm_pfs_context { - /** The PFS mount point */ - const char* c_mount; -}; - -/** The I/O requirements for a job */ -struct adm_job_requirements { - /** An array of input datasets */ - ADM_dataset_t* r_inputs; - /** The number of datasets in r_inputs */ - size_t r_num_inputs; - /** A list of output datasets */ - ADM_dataset_t* r_outputs; - /** The number of datasets in r_outputs */ - size_t r_num_outputs; - /** An optional definition for a specific adhoc storage instance */ - ADM_adhoc_context_t r_adhoc_ctx; -}; - -ADM_server_t -ADM_server_create(const char* protocol, const char* address) { - - struct adm_server* adm_server = - (struct adm_server*) malloc(sizeof(struct adm_server)); - - if(!adm_server) { - LOGGER_ERROR("Could not allocate ADM_server_t") - return NULL; - } - - adm_server->s_protocol = protocol; - adm_server->s_address = address; - - return adm_server; -} - -ADM_return_t -ADM_server_destroy(ADM_server_t server) { - ADM_return_t ret = ADM_SUCCESS; - - if(!server) { - LOGGER_ERROR("Invalid ADM_server_t") - return ADM_EBADARGS; - } - - free(server); - return ret; -} - - -ADM_node_t -ADM_node_create(const char* hostname) { - - struct adm_node* adm_node = - (struct adm_node*) malloc(sizeof(struct adm_node)); - - if(!adm_node) { - LOGGER_ERROR("Could not allocate ADM_node_t") - return NULL; - } - - adm_node->n_hostname = hostname; - - return adm_node; -} - -ADM_return_t -ADM_node_destroy(ADM_node_t node) { - ADM_return_t ret = ADM_SUCCESS; - - if(!node) { - LOGGER_ERROR("Invalid ADM_node_t") - return ADM_EBADARGS; - } - - free(node); - return ret; -} - - -ADM_dataset_t -ADM_dataset_create(const char* id) { - - struct adm_dataset* adm_dataset = - (struct adm_dataset*) malloc(sizeof(struct adm_dataset)); - - if(!adm_dataset) { - LOGGER_ERROR("Could not allocate ADM_dataset_t") - return NULL; - } - - adm_dataset->d_id = id; - - return adm_dataset; -} - -ADM_return_t -ADM_dataset_destroy(ADM_dataset_t dataset) { - ADM_return_t ret = ADM_SUCCESS; - - if(!dataset) { - LOGGER_ERROR("Invalid ADM_dataset_t") - return ADM_EBADARGS; - } - - free(dataset); - return ret; -} - -ADM_qos_entity_t -ADM_qos_entity_create(ADM_qos_scope_t scope, ...) { - - struct adm_qos_entity* adm_qos_entity = - (struct adm_qos_entity*) malloc(sizeof(struct adm_qos_entity)); - - if(!adm_qos_entity) { - LOGGER_ERROR("Could not allocate ADM_qos_entity_t") - return NULL; - } - - adm_qos_entity->e_scope = scope; - - va_list ap; - va_start(ap, scope); - - switch(scope) { - case ADM_QOS_SCOPE_NODE: - adm_qos_entity->e_node = va_arg(ap, ADM_node_t); - break; - case ADM_QOS_SCOPE_JOB: - adm_qos_entity->e_job = va_arg(ap, ADM_job_t); - break; - case ADM_QOS_SCOPE_DATASET: - adm_qos_entity->e_dataset = va_arg(ap, ADM_dataset_t); - break; - } - va_end(ap); - - return adm_qos_entity; -} - -ADM_return_t -ADM_qos_entity_destroy(ADM_qos_entity_t entity) { - - ADM_return_t ret = ADM_SUCCESS; - - if(!entity) { - LOGGER_ERROR("Invalid ADM_qos_entity_t") - return ADM_EBADARGS; - } - - free(entity); - return ret; -} - -ADM_qos_limit_t -ADM_qos_limit_create(ADM_qos_entity_t entity, ADM_qos_class_t cls, - uint64_t value) { - - struct adm_qos_limit* adm_qos_limit = - (struct adm_qos_limit*) malloc(sizeof(struct adm_qos_limit)); - - if(!adm_qos_limit) { - LOGGER_ERROR("Could not allocate ADM_qos_limit_t") - return NULL; - } - - adm_qos_limit->l_entity = entity; - adm_qos_limit->l_class = cls; - adm_qos_limit->l_value = value; - - return adm_qos_limit; -} - -ADM_return_t -ADM_qos_limit_destroy(ADM_qos_limit_t limit) { - ADM_return_t ret = ADM_SUCCESS; - - if(!limit) { - LOGGER_ERROR("Invalid ADM_qos_limit_t") - return ADM_EBADARGS; - } - - free(limit); - return ret; -} - -ADM_dataset_info_t -ADM_dataset_info_create() { - - struct adm_dataset_info* adm_dataset_info = - (struct adm_dataset_info*) malloc(sizeof(*adm_dataset_info)); - - if(!adm_dataset_info) { - LOGGER_ERROR("Could not allocate ADM_dataset_info_t"); - return NULL; - } - - return adm_dataset_info; -} - -ADM_return_t -ADM_dataset_info_destroy(ADM_dataset_info_t dataset_info) { - ADM_return_t ret = ADM_SUCCESS; - - if(!dataset_info) { - LOGGER_ERROR("Invalid ADM_dataset_info_t") - return ADM_EBADARGS; - } - - free(dataset_info); - return ret; -} - -ADM_storage_t -ADM_storage_create(const char* id, ADM_storage_type_t type, void* ctx) { - - struct adm_storage* adm_storage = - (struct adm_storage*) malloc(sizeof(*adm_storage)); - - if(!adm_storage) { - LOGGER_ERROR("Could not allocate ADM_storage_t"); - return NULL; - } - - if(!id) { - LOGGER_ERROR("Null storage id") - return NULL; - } - - if(!ctx) { - LOGGER_ERROR("Null storage context") - return NULL; - } - - adm_storage->s_id = id; - adm_storage->s_type = type; - - switch(adm_storage->s_type) { - case ADM_STORAGE_GEKKOFS: - case ADM_STORAGE_DATACLAY: - case ADM_STORAGE_EXPAND: - case ADM_STORAGE_HERCULES: - adm_storage->s_adhoc_ctx = *((ADM_adhoc_context_t*) ctx); - break; - - case ADM_STORAGE_LUSTRE: - case ADM_STORAGE_GPFS: - adm_storage->s_pfs_ctx = *((ADM_pfs_context_t*) ctx); - break; - } - - return adm_storage; -} - -ADM_return_t -ADM_storage_destroy(ADM_storage_t storage) { - - ADM_return_t ret = ADM_SUCCESS; - - if(!storage) { - LOGGER_ERROR("Invalid ADM_storage_t") - return ADM_EBADARGS; - } - - free(storage); - return ret; -} - -ADM_storage_resources_t -ADM_storage_resources_create() { - - struct adm_storage_resources* adm_storage_resources = - (struct adm_storage_resources*) malloc( - sizeof(*adm_storage_resources)); - - if(!adm_storage_resources) { - LOGGER_ERROR("Could not allocate ADM_storage_resources_t"); - return NULL; - } - - return adm_storage_resources; -} - -ADM_return_t -ADM_storage_resources_destroy(ADM_storage_resources_t res) { - - ADM_return_t ret = ADM_SUCCESS; - - if(!res) { - LOGGER_ERROR("Invalid ADM_storage_resources_t") - return ADM_EBADARGS; - } - - free(res); - return ret; -} - -ADM_data_operation_t -ADM_data_operation_create() { - - struct adm_data_operation* adm_data_operation = - (struct adm_data_operation*) malloc(sizeof(*adm_data_operation)); - - if(!adm_data_operation) { - LOGGER_ERROR("Could not allocate ADM_data_operation_t"); - return NULL; - } - - return adm_data_operation; -} - -ADM_return_t -ADM_data_operation_destroy(ADM_data_operation_t op) { - - ADM_return_t ret = ADM_SUCCESS; - - if(!op) { - LOGGER_ERROR("Invalid ADM_data_operation_t") - return ADM_EBADARGS; - } - - free(op); - return ret; -} - - -ADM_adhoc_context_t -ADM_adhoc_context_create(ADM_adhoc_mode_t exec_mode, - ADM_adhoc_access_t access_type, uint32_t nodes, - uint32_t walltime, bool should_flush) { - - struct adm_adhoc_context* adm_adhoc_context = - (struct adm_adhoc_context*) malloc(sizeof(*adm_adhoc_context)); - - if(!adm_adhoc_context) { - LOGGER_ERROR("Could not allocate ADM_adhoc_context_t"); - return NULL; - } - - adm_adhoc_context->c_mode = exec_mode; - adm_adhoc_context->c_access = access_type; - adm_adhoc_context->c_nodes = nodes; - adm_adhoc_context->c_walltime = walltime; - adm_adhoc_context->c_should_bg_flush = should_flush; - - return adm_adhoc_context; -} - -ADM_return_t -ADM_adhoc_context_destroy(ADM_adhoc_context_t ctx) { - - - ADM_return_t ret = ADM_SUCCESS; - - if(!ctx) { - LOGGER_ERROR("Invalid ADM_adhoc_context_t") - return ADM_EBADARGS; - } - - free(ctx); - return ret; -} - -ADM_pfs_context_t -ADM_pfs_context_create(const char* mountpoint) { - - struct adm_pfs_context* adm_pfs_context = - (struct adm_pfs_context*) malloc(sizeof(*adm_pfs_context)); - - if(!adm_pfs_context) { - LOGGER_ERROR("Could not allocate ADM_adhoc_context_t"); - return NULL; - } - - adm_pfs_context->c_mount = mountpoint; - - return adm_pfs_context; -} - -ADM_return_t -ADM_pfs_context_destroy(ADM_pfs_context_t ctx) { - ADM_return_t ret = ADM_SUCCESS; - - if(!ctx) { - LOGGER_ERROR("Invalid ADM_pfs_context_t") - return ADM_EBADARGS; - } - - free(ctx); - return ret; -} - -ADM_job_requirements_t -ADM_job_requirements_create(ADM_dataset_t inputs[], size_t inputs_len, - ADM_dataset_t outputs[], size_t outputs_len, - ADM_storage_t storage) { - - struct adm_job_requirements* adm_job_reqs = - (struct adm_job_requirements*) malloc( - sizeof(struct adm_job_requirements)); - - if(!adm_job_reqs) { - LOGGER_ERROR("Could not allocate ADM_job_requirements_t") - return NULL; - } - - adm_job_reqs->r_inputs = inputs; - adm_job_reqs->r_num_inputs = inputs_len; - adm_job_reqs->r_outputs = outputs; - adm_job_reqs->r_num_outputs = outputs_len; - adm_job_reqs->r_adhoc_ctx = NULL; - - if(storage) { - if(storage->s_type != ADM_STORAGE_GEKKOFS && - storage->s_type != ADM_STORAGE_DATACLAY && - storage->s_type != ADM_STORAGE_EXPAND && - storage->s_type != ADM_STORAGE_HERCULES) { - LOGGER_ERROR("Invalid adhoc_storage") - return NULL; - } - adm_job_reqs->r_adhoc_ctx = storage->s_adhoc_ctx; - } - - return adm_job_reqs; -} - -ADM_return_t -ADM_job_requirements_destroy(ADM_job_requirements_t reqs) { - ADM_return_t ret = ADM_SUCCESS; - - if(!reqs) { - LOGGER_ERROR("Invalid ADM_job_requirements_t") - return ADM_EBADARGS; - } - - free(reqs); - return ret; -} - -/** - * Initialize a job handle that can be used by clients to refer to a job. - * - * @remark This function is not actually part of the public API, but it is - * useful to have for internal purposes - * - * @param [in] id The identifier for this job - * @return A valid JOB HANDLE or NULL in case of failure. - */ -static ADM_job_t -ADM_job_create(uint64_t id) { - - struct adm_job* adm_job = (struct adm_job*) malloc(sizeof(struct adm_job)); - - if(!adm_job) { - LOGGER_ERROR("Could not allocate ADM_job_t") - return NULL; - } - - adm_job->j_id = id; - - return adm_job; -} - - /******************************************************************************/ /* C API implementation */ /******************************************************************************/ ADM_return_t ADM_ping(ADM_server_t server) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::detail::ping(srv); } @@ -581,21 +45,16 @@ ADM_return_t ADM_register_job(ADM_server_t server, ADM_job_requirements_t reqs, ADM_job_t* job) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; - const auto rv = admire::detail::register_job(srv, reqs); + const auto rv = + admire::detail::register_job(srv, admire::job_requirements{reqs}); if(!rv) { return rv.error(); } - const auto jh = ADM_job_create(rv->m_id); - - if(!jh) { - return ADM_EOTHER; - } - - *job = jh; + *job = admire::job{rv->m_id}.to_ctype(); return ADM_SUCCESS; } @@ -604,17 +63,30 @@ ADM_return_t ADM_update_job(ADM_server_t server, ADM_job_t job, ADM_job_requirements_t reqs) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; - return admire::update_job(srv, job, reqs); + const auto rv = admire::detail::update_job(srv, admire::job{job}, + admire::job_requirements{reqs}); + + if(!rv) { + return rv.error(); + } + + return ADM_SUCCESS; } ADM_return_t ADM_remove_job(ADM_server_t server, ADM_job_t job) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; - return admire::remove_job(srv, job); + const auto rv = admire::detail::remove_job(srv, admire::job{job}); + + if(!rv) { + return rv.error(); + } + + return ADM_SUCCESS; } ADM_return_t @@ -622,16 +94,27 @@ ADM_register_adhoc_storage(ADM_server_t server, ADM_job_t job, ADM_adhoc_context_t ctx, ADM_storage_t* adhoc_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; + + const auto rv = admire::detail::register_adhoc_storage( + srv, admire::job{job}, admire::adhoc_storage::context{ctx}); + //admire::adhoc_storage::storage{adhoc_storage}); - return admire::register_adhoc_storage(srv, job, ctx, adhoc_storage); + if(!rv) { + return rv.error(); + } + + *adhoc_storage = admire::managed_rpc_type{*rv}.get(); + + + return ADM_SUCCESS; } ADM_return_t ADM_update_adhoc_storage(ADM_server_t server, ADM_job_t job, ADM_adhoc_context_t ctx, ADM_storage_t adhoc_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::update_adhoc_storage(srv, job, ctx, adhoc_storage); } @@ -640,7 +123,7 @@ ADM_return_t ADM_remove_adhoc_storage(ADM_server_t server, ADM_job_t job, ADM_storage_t adhoc_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::remove_adhoc_storage(srv, job, adhoc_storage); } @@ -649,7 +132,7 @@ ADM_return_t ADM_deploy_adhoc_storage(ADM_server_t server, ADM_job_t job, ADM_storage_t adhoc_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::deploy_adhoc_storage(srv, job, adhoc_storage); } @@ -658,7 +141,7 @@ ADM_return_t ADM_register_pfs_storage(ADM_server_t server, ADM_job_t job, ADM_pfs_context_t ctx, ADM_storage_t* pfs_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::register_pfs_storage(srv, job, ctx, pfs_storage); } @@ -667,7 +150,7 @@ ADM_return_t ADM_update_pfs_storage(ADM_server_t server, ADM_job_t job, ADM_pfs_context_t ctx, ADM_storage_t pfs_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::update_pfs_storage(srv, job, ctx, pfs_storage); } @@ -676,7 +159,7 @@ ADM_return_t ADM_remove_pfs_storage(ADM_server_t server, ADM_job_t job, ADM_storage_t pfs_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::remove_pfs_storage(srv, job, pfs_storage); } @@ -687,7 +170,7 @@ ADM_transfer_dataset(ADM_server_t server, ADM_job_t job, ADM_qos_limit_t** limits, ADM_transfer_mapping_t mapping, ADM_transfer_t* transfer) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::transfer_dataset(srv, job, sources, targets, limits, mapping, transfer); @@ -697,7 +180,7 @@ ADM_return_t ADM_set_dataset_information(ADM_server_t server, ADM_job_t job, ADM_dataset_t target, ADM_dataset_info_t info) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::set_dataset_information(srv, job, target, info); } @@ -706,7 +189,7 @@ ADM_return_t ADM_set_io_resources(ADM_server_t server, ADM_job_t job, ADM_storage_t tier, ADM_storage_resources_t resources) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::set_io_resources(srv, job, tier, resources); } @@ -716,7 +199,7 @@ ADM_get_transfer_priority(ADM_server_t server, ADM_job_t job, ADM_transfer_t transfer, ADM_transfer_priority_t* priority) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::get_transfer_priority(srv, job, transfer, priority); } @@ -725,7 +208,7 @@ ADM_return_t ADM_set_transfer_priority(ADM_server_t server, ADM_job_t job, ADM_transfer_t transfer, int incr) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::set_transfer_priority(srv, job, transfer, incr); } @@ -734,7 +217,7 @@ ADM_return_t ADM_cancel_transfer(ADM_server_t server, ADM_job_t job, ADM_transfer_t transfer) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::cancel_transfer(srv, job, transfer); } @@ -743,7 +226,7 @@ ADM_return_t ADM_get_pending_transfers(ADM_server_t server, ADM_job_t job, ADM_transfer_t** pending_transfers) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::get_pending_transfers(srv, job, pending_transfers); } @@ -752,7 +235,7 @@ ADM_return_t ADM_set_qos_constraints(ADM_server_t server, ADM_job_t job, ADM_qos_entity_t entity, ADM_qos_limit_t limit) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::set_qos_constraints(srv, job, entity, limit); } @@ -761,7 +244,7 @@ ADM_return_t ADM_get_qos_constraints(ADM_server_t server, ADM_job_t job, ADM_qos_entity_t entity, ADM_qos_limit_t** limits) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::get_qos_constraints(srv, job, entity, limits); } @@ -770,7 +253,7 @@ ADM_return_t ADM_define_data_operation(ADM_server_t server, ADM_job_t job, const char* path, ADM_data_operation_t* op, ...) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; va_list args; va_start(args, op); @@ -785,7 +268,7 @@ ADM_connect_data_operation(ADM_server_t server, ADM_job_t job, ADM_dataset_t input, ADM_dataset_t output, bool should_stream, ...) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; va_list args; va_start(args, should_stream); @@ -801,7 +284,7 @@ ADM_finalize_data_operation(ADM_server_t server, ADM_job_t job, ADM_data_operation_t op, ADM_data_operation_status_t* status) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::finalize_data_operation(srv, job, op, status); } @@ -811,7 +294,7 @@ ADM_link_transfer_to_data_operation(ADM_server_t server, ADM_job_t job, ADM_data_operation_t op, bool should_stream, ...) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; va_list args; va_start(args, should_stream); @@ -825,6 +308,6 @@ ADM_link_transfer_to_data_operation(ADM_server_t server, ADM_job_t job, ADM_return_t ADM_get_statistics(ADM_server_t server, ADM_job_t job, ADM_job_stats_t** stats) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::get_statistics(srv, job, stats); } diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index 4b28664256709245f3f978fd80be59ccd64dd65f..b9390e3c4b20fc3a5ba8e61be632007ab87948fe 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -23,131 +23,126 @@ *****************************************************************************/ #include -#include -#include "rpcs/public.hpp" +#include +#include +#include #include "impl.hpp" void rpc_registration_cb(scord::network::rpc_client* client) { - REGISTER_RPC(client, "ADM_ping", void, void, ADM_ping, false); + REGISTER_RPC(client, "ADM_ping", void, void, NULL, false); REGISTER_RPC(client, "ADM_register_job", ADM_register_job_in_t, - ADM_register_job_out_t, ADM_register_job, true); + ADM_register_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_update_job", ADM_update_job_in_t, - ADM_update_job_out_t, ADM_update_job, true); + ADM_update_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_remove_job", ADM_remove_job_in_t, - ADM_remove_job_out_t, ADM_remove_job, true); + ADM_remove_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_register_adhoc_storage", ADM_register_adhoc_storage_in_t, - ADM_register_adhoc_storage_out_t, ADM_register_adhoc_storage, - true); + ADM_register_adhoc_storage_out_t, NULL, true); REGISTER_RPC(client, "ADM_update_adhoc_storage", ADM_update_adhoc_storage_in_t, ADM_update_adhoc_storage_out_t, - ADM_update_adhoc_storage, true); + NULL, true); REGISTER_RPC(client, "ADM_remove_adhoc_storage", ADM_remove_adhoc_storage_in_t, ADM_remove_adhoc_storage_out_t, - ADM_remove_adhoc_storage, true); + NULL, true); REGISTER_RPC(client, "ADM_deploy_adhoc_storage", ADM_deploy_adhoc_storage_in_t, ADM_deploy_adhoc_storage_out_t, - ADM_deploy_adhoc_storage, true); + NULL, true); - REGISTER_RPC(client, "ADM_input", ADM_input_in_t, ADM_input_out_t, - ADM_input, true); + REGISTER_RPC(client, "ADM_input", ADM_input_in_t, ADM_input_out_t, NULL, + true); - REGISTER_RPC(client, "ADM_output", ADM_output_in_t, ADM_output_out_t, - ADM_output, true); + REGISTER_RPC(client, "ADM_output", ADM_output_in_t, ADM_output_out_t, NULL, + true); - REGISTER_RPC(client, "ADM_inout", ADM_inout_in_t, ADM_inout_out_t, - ADM_inout, true); + REGISTER_RPC(client, "ADM_inout", ADM_inout_in_t, ADM_inout_out_t, NULL, + true); REGISTER_RPC(client, "ADM_adhoc_context", ADM_adhoc_context_in_t, - ADM_adhoc_context_out_t, ADM_adhoc_context, true); + ADM_adhoc_context_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_context_id", ADM_adhoc_context_id_in_t, - ADM_adhoc_context_id_out_t, ADM_adhoc_context_id, true); + ADM_adhoc_context_id_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_nodes", ADM_adhoc_nodes_in_t, - ADM_adhoc_nodes_out_t, ADM_adhoc_nodes, true); + ADM_adhoc_nodes_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_walltime", ADM_adhoc_walltime_in_t, - ADM_adhoc_walltime_out_t, ADM_adhoc_walltime, true); + ADM_adhoc_walltime_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_access", ADM_adhoc_access_in_t, - ADM_adhoc_access_out_t, ADM_adhoc_access, true); + ADM_adhoc_access_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_distribution", ADM_adhoc_distribution_in_t, - ADM_adhoc_distribution_out_t, ADM_adhoc_distribution, true); + ADM_adhoc_distribution_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_background_flush", ADM_adhoc_background_flush_in_t, - ADM_adhoc_background_flush_out_t, ADM_adhoc_background_flush, - true); + ADM_adhoc_background_flush_out_t, NULL, true); REGISTER_RPC(client, "ADM_in_situ_ops", ADM_in_situ_ops_in_t, - ADM_in_situ_ops_out_t, ADM_in_situ_ops, true); + ADM_in_situ_ops_out_t, NULL, true); REGISTER_RPC(client, "ADM_in_transit_ops", ADM_in_transit_ops_in_t, - ADM_in_transit_ops_out_t, ADM_in_transit_ops, true); + ADM_in_transit_ops_out_t, NULL, true); REGISTER_RPC(client, "ADM_transfer_dataset", ADM_transfer_dataset_in_t, - ADM_transfer_dataset_out_t, ADM_transfer_dataset, true); + ADM_transfer_dataset_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_dataset_information", ADM_set_dataset_information_in_t, - ADM_set_dataset_information_out_t, ADM_set_dataset_information, - true); + ADM_set_dataset_information_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_io_resources", ADM_set_io_resources_in_t, - ADM_set_io_resources_out_t, ADM_set_io_resources, true); + ADM_set_io_resources_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_get_transfer_priority", ADM_get_transfer_priority_in_t, - ADM_get_transfer_priority_out_t, ADM_get_transfer_priority, true); + REGISTER_RPC(client, "ADM_get_transfer_priority", + ADM_get_transfer_priority_in_t, + ADM_get_transfer_priority_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_set_transfer_priority", ADM_set_transfer_priority_in_t, - ADM_set_transfer_priority_out_t, ADM_set_transfer_priority, true); + REGISTER_RPC(client, "ADM_set_transfer_priority", + ADM_set_transfer_priority_in_t, + ADM_set_transfer_priority_out_t, NULL, true); REGISTER_RPC(client, "ADM_cancel_transfer", ADM_cancel_transfer_in_t, - ADM_cancel_transfer_out_t, ADM_cancel_transfer, true); + ADM_cancel_transfer_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_get_pending_transfers", ADM_get_pending_transfers_in_t, - ADM_get_pending_transfers_out_t, ADM_get_pending_transfers, true); + REGISTER_RPC(client, "ADM_get_pending_transfers", + ADM_get_pending_transfers_in_t, + ADM_get_pending_transfers_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_qos_constraints", ADM_set_qos_constraints_in_t, ADM_set_qos_constraints_out_t, - ADM_set_qos_constraints, true); + NULL, true); REGISTER_RPC(client, "ADM_get_qos_constraints", ADM_get_qos_constraints_in_t, ADM_get_qos_constraints_out_t, - ADM_get_qos_constraints, true); + NULL, true); - REGISTER_RPC( - client, "ADM_define_data_operation", ADM_define_data_operation_in_t, - ADM_define_data_operation_out_t, ADM_define_data_operation, true); + REGISTER_RPC(client, "ADM_define_data_operation", + ADM_define_data_operation_in_t, + ADM_define_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_connect_data_operation", ADM_connect_data_operation_in_t, - ADM_connect_data_operation_out_t, ADM_connect_data_operation, - true); + ADM_connect_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_finalize_data_operation", ADM_finalize_data_operation_in_t, - ADM_finalize_data_operation_out_t, ADM_finalize_data_operation, - true); + ADM_finalize_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_link_transfer_to_data_operation", ADM_link_transfer_to_data_operation_in_t, - ADM_link_transfer_to_data_operation_out_t, - ADM_link_transfer_to_data_operation, true); + ADM_link_transfer_to_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_get_statistics", ADM_get_statistics_in_t, - ADM_get_statistics_out_t, ADM_get_statistics, true); + ADM_get_statistics_out_t, NULL, true); } namespace admire::detail { @@ -166,18 +161,22 @@ ping(const server& srv) { return ADM_SUCCESS; } + tl::expected -register_job(const admire::server& srv, ADM_job_requirements_t reqs) { - (void) srv; - (void) reqs; +register_job(const admire::server& srv, const admire::job_requirements& reqs) { + + using scord::utils::c_ptr; + using job_requirements_ptr = + c_ptr; + const auto preqs = job_requirements_ptr{reqs.to_rpc_type()}; scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; auto endp = rpc_client.lookup(srv.m_address); - LOGGER_INFO("ADM_register_job(...)"); + LOGGER_INFO("RPC ({}): {{{}}}", "ADM_register_job", reqs); - ADM_register_job_in_t in{}; + ADM_register_job_in_t in{*preqs}; ADM_register_job_out_t out; endp.call("ADM_register_job", &in, &out); @@ -191,4 +190,85 @@ register_job(const admire::server& srv, ADM_job_requirements_t reqs) { return admire::job{42}; } +tl::expected +update_job(const admire::server& srv, const admire::job& job, + const admire::job_requirements& reqs) { + + using scord::utils::c_ptr; + using job_requirements_ptr = + c_ptr; + const auto preqs = job_requirements_ptr{reqs.to_rpc_type()}; + + scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + + auto endp = rpc_client.lookup(srv.m_address); + + LOGGER_INFO("RPC ({}): {{{}}}", "ADM_update_job", reqs); + + ADM_update_job_in_t in{}; + ADM_update_job_out_t out; + + endp.call("ADM_update_job", &in, &out); + + if(out.ret < 0) { + LOGGER_ERROR("ADM_update_job() = {}", out.ret); + return tl::make_unexpected(static_cast(out.ret)); + } + + LOGGER_INFO("ADM_update_job() = {}", ADM_SUCCESS); + return admire::job{42}; +} + +tl::expected +remove_job(const admire::server& srv, const admire::job& job) { + + scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + + auto endp = rpc_client.lookup(srv.m_address); + + // LOGGER_INFO("RPC ({}): {{{}}}", "ADM_remove_job", reqs); + // TODO: check how to proceed when reqs is not an argument + LOGGER_INFO("ADM_remove_job(...)"); + + ADM_remove_job_in_t in{}; + ADM_remove_job_out_t out; + + endp.call("ADM_remove_job", &in, &out); + + if(out.ret < 0) { + LOGGER_ERROR("ADM_remove_job() = {}", out.ret); + return tl::make_unexpected(static_cast(out.ret)); + } + + LOGGER_INFO("ADM_remove_job() = {}", ADM_SUCCESS); + return admire::job{42}; +} + +tl::expected +register_adhoc_storage(const admire::server& srv, const admire::job& job, + const admire::adhoc_storage::context& ctx){ + + scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + + auto endp = rpc_client.lookup(srv.m_address); + + // TODO: check how to proceed when reqs is not an argument + LOGGER_INFO("ADM_register_adhoc_storage(...)"); + + ADM_register_adhoc_storage_in_t in{}; + ADM_register_adhoc_storage_out_t out; + + endp.call("ADM_register_adhoc_storage", &in, &out); + + if(out.ret < 0) { + LOGGER_ERROR("ADM_register_adhoc_storage() = {}", out.ret); + return static_cast(out.ret); + } + + LOGGER_INFO("ADM_register_adhoc_storage() = {}", ADM_SUCCESS); + return admire::adhoc_storage{"read-only", 10, ctx}; + + // TODO: take a look about what the return! +} + } // namespace admire::detail diff --git a/src/lib/detail/impl.hpp b/src/lib/detail/impl.hpp index cacc056ff3572e735014d77a21472acd3cd18079..2fe2a5cfc4b63173604ea79481db834502291843 100644 --- a/src/lib/detail/impl.hpp +++ b/src/lib/detail/impl.hpp @@ -27,6 +27,7 @@ #define SCORD_ADMIRE_IMPL_HPP #include +#include namespace admire { using error_code = ADM_return_t; @@ -38,7 +39,17 @@ admire::error_code ping(const server& srv); tl::expected -register_job(const server& srv, ADM_job_requirements_t reqs); +register_job(const server& srv, const job_requirements& reqs); + +tl::expected +update_job(const server& srv, const job& job, const job_requirements& reqs); + +tl::expected +remove_job(const server& srv, const job& job); + +tl::expected +register_adhoc_storage(const server& srv, const job& job, + const admire::adhoc_storage::context& ctx); } // namespace admire::detail diff --git a/src/lib/types.cpp b/src/lib/types.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5913b838dfa883166b9df954a015e4d5f37665dd --- /dev/null +++ b/src/lib/types.cpp @@ -0,0 +1,791 @@ +/****************************************************************************** + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include "admire_types.hpp" + +/******************************************************************************/ +/* C Type definitions and related functions */ +/******************************************************************************/ + +struct adm_server { + const char* s_protocol; + const char* s_address; +}; + +ADM_server_t +ADM_server_create(const char* protocol, const char* address) { + + struct adm_server* adm_server = + (struct adm_server*) malloc(sizeof(struct adm_server)); + + if(!adm_server) { + LOGGER_ERROR("Could not allocate ADM_server_t") + return NULL; + } + + adm_server->s_protocol = protocol; + adm_server->s_address = address; + + return adm_server; +} + +ADM_return_t +ADM_server_destroy(ADM_server_t server) { + ADM_return_t ret = ADM_SUCCESS; + + if(!server) { + LOGGER_ERROR("Invalid ADM_server_t") + return ADM_EBADARGS; + } + + free(server); + return ret; +} + + +ADM_node_t +ADM_node_create(const char* hostname) { + + struct adm_node* adm_node = + (struct adm_node*) malloc(sizeof(struct adm_node)); + + if(!adm_node) { + LOGGER_ERROR("Could not allocate ADM_node_t") + return NULL; + } + + adm_node->n_hostname = hostname; + + return adm_node; +} + +ADM_return_t +ADM_node_destroy(ADM_node_t node) { + ADM_return_t ret = ADM_SUCCESS; + + if(!node) { + LOGGER_ERROR("Invalid ADM_node_t") + return ADM_EBADARGS; + } + + free(node); + return ret; +} + + +ADM_dataset_t +ADM_dataset_create(const char* id) { + + struct adm_dataset* adm_dataset = + (struct adm_dataset*) calloc(1, sizeof(struct adm_dataset)); + + if(!adm_dataset) { + LOGGER_ERROR("Could not allocate ADM_dataset_t") + return NULL; + } + + if(id) { + size_t n = strlen(id); + adm_dataset->d_id = (const char*) calloc(n + 1, sizeof(char)); + strcpy((char*) adm_dataset->d_id, id); + } + + return adm_dataset; +} + +ADM_dataset_t +ADM_dataset_copy(ADM_dataset_t dst, const ADM_dataset_t src) { + + if(!src || !dst) { + return NULL; + } + + // copy all primitive types + *dst = *src; + + // duplicate copy any pointer types + if(src->d_id) { + size_t n = strlen(src->d_id); + dst->d_id = (const char*) calloc(n + 1, sizeof(char)); + strncpy((char*) dst->d_id, src->d_id, n); + } + + return dst; +} + +ADM_return_t +ADM_dataset_destroy(ADM_dataset_t dataset) { + ADM_return_t ret = ADM_SUCCESS; + + if(!dataset) { + LOGGER_ERROR("Invalid ADM_dataset_t") + return ADM_EBADARGS; + } + + if(dataset->d_id) { + free((void*) dataset->d_id); + } + + free(dataset); + return ret; +} + +ADM_qos_entity_t +ADM_qos_entity_create(ADM_qos_scope_t scope, ...) { + + struct adm_qos_entity* adm_qos_entity = + (struct adm_qos_entity*) malloc(sizeof(struct adm_qos_entity)); + + if(!adm_qos_entity) { + LOGGER_ERROR("Could not allocate ADM_qos_entity_t") + return NULL; + } + + adm_qos_entity->e_scope = scope; + + va_list ap; + va_start(ap, scope); + + switch(scope) { + case ADM_QOS_SCOPE_NODE: + adm_qos_entity->e_node = va_arg(ap, ADM_node_t); + break; + case ADM_QOS_SCOPE_JOB: + adm_qos_entity->e_job = va_arg(ap, ADM_job_t); + break; + case ADM_QOS_SCOPE_DATASET: + adm_qos_entity->e_dataset = va_arg(ap, ADM_dataset_t); + break; + } + va_end(ap); + + return adm_qos_entity; +} + +ADM_return_t +ADM_qos_entity_destroy(ADM_qos_entity_t entity) { + + ADM_return_t ret = ADM_SUCCESS; + + if(!entity) { + LOGGER_ERROR("Invalid ADM_qos_entity_t") + return ADM_EBADARGS; + } + + free(entity); + return ret; +} + +ADM_qos_limit_t +ADM_qos_limit_create(ADM_qos_entity_t entity, ADM_qos_class_t cls, + uint64_t value) { + + struct adm_qos_limit* adm_qos_limit = + (struct adm_qos_limit*) malloc(sizeof(struct adm_qos_limit)); + + if(!adm_qos_limit) { + LOGGER_ERROR("Could not allocate ADM_qos_limit_t") + return NULL; + } + + adm_qos_limit->l_entity = entity; + adm_qos_limit->l_class = cls; + adm_qos_limit->l_value = value; + + return adm_qos_limit; +} + +ADM_return_t +ADM_qos_limit_destroy(ADM_qos_limit_t limit) { + ADM_return_t ret = ADM_SUCCESS; + + if(!limit) { + LOGGER_ERROR("Invalid ADM_qos_limit_t") + return ADM_EBADARGS; + } + + free(limit); + return ret; +} + +ADM_dataset_info_t +ADM_dataset_info_create() { + + struct adm_dataset_info* adm_dataset_info = + (struct adm_dataset_info*) malloc(sizeof(*adm_dataset_info)); + + if(!adm_dataset_info) { + LOGGER_ERROR("Could not allocate ADM_dataset_info_t"); + return NULL; + } + + return adm_dataset_info; +} + +ADM_return_t +ADM_dataset_info_destroy(ADM_dataset_info_t dataset_info) { + ADM_return_t ret = ADM_SUCCESS; + + if(!dataset_info) { + LOGGER_ERROR("Invalid ADM_dataset_info_t") + return ADM_EBADARGS; + } + + free(dataset_info); + return ret; +} + +ADM_dataset_list_t +ADM_dataset_list_create(ADM_dataset_t datasets[], size_t length) { + + ADM_dataset_list_t p = (ADM_dataset_list_t) malloc(sizeof(*p)); + + if(!p) { + LOGGER_ERROR("Could not allocate ADM_dataset_list_t") + return NULL; + } + + const char* error_msg = NULL; + + p->l_length = length; + p->l_datasets = (struct adm_dataset*) calloc(length, sizeof(adm_dataset)); + + if(!p->l_datasets) { + error_msg = "Could not allocate ADM_dataset_list_t"; + goto cleanup_on_error; + } + + for(size_t i = 0; i < length; ++i) { + if(!ADM_dataset_copy(&p->l_datasets[i], datasets[i])) { + error_msg = "Could not allocate ADM_dataset_list_t"; + goto cleanup_on_error; + }; + } + + return p; + +cleanup_on_error: + if(p->l_datasets) { + free(p->l_datasets); + } + free(p); + + if(error_msg) { + LOGGER_ERROR(error_msg); + } + + return NULL; +} + +ADM_return_t +ADM_dataset_list_destroy(ADM_dataset_list_t list) { + ADM_return_t ret = ADM_SUCCESS; + + if(!list) { + LOGGER_ERROR("Invalid ADM_pfs_context_t") + return ADM_EBADARGS; + } + + // We cannot call ADM_dataset_destroy here because adm_datasets + // are stored as a consecutive array in memory. Thus, we free + // the dataset ids themselves and then the array. + if(list->l_datasets) { + for(size_t i = 0; i < list->l_length; ++i) { + free((void*) list->l_datasets[i].d_id); + } + free(list->l_datasets); + } + + free(list); + return ret; +} + +ADM_storage_t +ADM_storage_create(const char* id, ADM_storage_type_t type, void* ctx) { + + struct adm_storage* adm_storage = + (struct adm_storage*) malloc(sizeof(*adm_storage)); + + if(!adm_storage) { + LOGGER_ERROR("Could not allocate ADM_storage_t"); + return NULL; + } + + if(!id) { + LOGGER_ERROR("Null storage id") + return NULL; + } + + if(!ctx) { + LOGGER_ERROR("Null storage context") + return NULL; + } + + adm_storage->s_id = id; + adm_storage->s_type = type; + + switch(adm_storage->s_type) { + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + adm_storage->s_adhoc_ctx = *(adm_adhoc_context*) ctx; + break; + + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + adm_storage->s_pfs_ctx = *(adm_pfs_context*) ctx; + break; + } + + return adm_storage; +} + +ADM_return_t +ADM_storage_destroy(ADM_storage_t storage) { + + ADM_return_t ret = ADM_SUCCESS; + + if(!storage) { + LOGGER_ERROR("Invalid ADM_storage_t") + return ADM_EBADARGS; + } + + free(storage); + return ret; +} + +ADM_storage_resources_t +ADM_storage_resources_create() { + + struct adm_storage_resources* adm_storage_resources = + (struct adm_storage_resources*) malloc( + sizeof(*adm_storage_resources)); + + if(!adm_storage_resources) { + LOGGER_ERROR("Could not allocate ADM_storage_resources_t"); + return NULL; + } + + return adm_storage_resources; +} + +ADM_return_t +ADM_storage_resources_destroy(ADM_storage_resources_t res) { + + ADM_return_t ret = ADM_SUCCESS; + + if(!res) { + LOGGER_ERROR("Invalid ADM_storage_resources_t") + return ADM_EBADARGS; + } + + free(res); + return ret; +} + +ADM_data_operation_t +ADM_data_operation_create() { + + struct adm_data_operation* adm_data_operation = + (struct adm_data_operation*) malloc(sizeof(*adm_data_operation)); + + if(!adm_data_operation) { + LOGGER_ERROR("Could not allocate ADM_data_operation_t"); + return NULL; + } + + return adm_data_operation; +} + +ADM_return_t +ADM_data_operation_destroy(ADM_data_operation_t op) { + + ADM_return_t ret = ADM_SUCCESS; + + if(!op) { + LOGGER_ERROR("Invalid ADM_data_operation_t") + return ADM_EBADARGS; + } + + free(op); + return ret; +} + + +ADM_adhoc_context_t +ADM_adhoc_context_create(ADM_adhoc_mode_t exec_mode, + ADM_adhoc_access_t access_type, uint32_t nodes, + uint32_t walltime, bool should_flush) { + + struct adm_adhoc_context* adm_adhoc_context = + (struct adm_adhoc_context*) malloc(sizeof(*adm_adhoc_context)); + + if(!adm_adhoc_context) { + LOGGER_ERROR("Could not allocate ADM_adhoc_context_t"); + return NULL; + } + + adm_adhoc_context->c_mode = exec_mode; + adm_adhoc_context->c_access = access_type; + adm_adhoc_context->c_nodes = nodes; + adm_adhoc_context->c_walltime = walltime; + adm_adhoc_context->c_should_bg_flush = should_flush; + + return adm_adhoc_context; +} + +ADM_return_t +ADM_adhoc_context_destroy(ADM_adhoc_context_t ctx) { + + + ADM_return_t ret = ADM_SUCCESS; + + if(!ctx) { + LOGGER_ERROR("Invalid ADM_adhoc_context_t") + return ADM_EBADARGS; + } + + free(ctx); + return ret; +} + +ADM_pfs_context_t +ADM_pfs_context_create(const char* mountpoint) { + + struct adm_pfs_context* adm_pfs_context = + (struct adm_pfs_context*) malloc(sizeof(*adm_pfs_context)); + + if(!adm_pfs_context) { + LOGGER_ERROR("Could not allocate ADM_adhoc_context_t"); + return NULL; + } + + adm_pfs_context->c_mount = mountpoint; + + return adm_pfs_context; +} + +ADM_return_t +ADM_pfs_context_destroy(ADM_pfs_context_t ctx) { + ADM_return_t ret = ADM_SUCCESS; + + if(!ctx) { + LOGGER_ERROR("Invalid ADM_pfs_context_t") + return ADM_EBADARGS; + } + + free(ctx); + return ret; +} + +ADM_job_requirements_t +ADM_job_requirements_create(ADM_dataset_t inputs[], size_t inputs_len, + ADM_dataset_t outputs[], size_t outputs_len, + ADM_storage_t storage) { + + struct adm_job_requirements* adm_job_reqs = + (struct adm_job_requirements*) malloc( + sizeof(struct adm_job_requirements)); + + if(!adm_job_reqs) { + LOGGER_ERROR("Could not allocate ADM_job_requirements_t") + return NULL; + } + + ADM_dataset_list_t inputs_list = NULL; + ADM_dataset_list_t outputs_list = NULL; + const char* error_msg = NULL; + + inputs_list = ADM_dataset_list_create(inputs, inputs_len); + + if(!inputs_list) { + error_msg = "Could not allocate ADM_job_requirements_t"; + goto cleanup_on_error; + } + + outputs_list = ADM_dataset_list_create(outputs, outputs_len); + + if(!outputs_list) { + error_msg = "Could not allocate ADM_job_requirements_t"; + goto cleanup_on_error; + } + + adm_job_reqs->r_inputs = inputs_list; + adm_job_reqs->r_outputs = outputs_list; + adm_job_reqs->r_storage = storage; + + if(!storage) { + return adm_job_reqs; + } + + if(storage->s_type != ADM_STORAGE_GEKKOFS && + storage->s_type != ADM_STORAGE_DATACLAY && + storage->s_type != ADM_STORAGE_EXPAND && + storage->s_type != ADM_STORAGE_HERCULES) { + error_msg = "Invalid adhoc_storage argument"; + goto cleanup_on_error; + } + + return adm_job_reqs; + +cleanup_on_error: + + if(outputs_list) { + ADM_dataset_list_destroy(outputs_list); + } + + if(inputs_list) { + ADM_dataset_list_destroy(inputs_list); + } + + if(adm_job_reqs) { + ADM_job_requirements_destroy(adm_job_reqs); + } + + if(error_msg) { + LOGGER_ERROR(error_msg); + } + + return NULL; +} + +ADM_return_t +ADM_job_requirements_destroy(ADM_job_requirements_t reqs) { + ADM_return_t ret = ADM_SUCCESS; + + if(!reqs) { + LOGGER_ERROR("Invalid ADM_job_requirements_t") + return ADM_EBADARGS; + } + + if(reqs->r_inputs) { + ADM_dataset_list_destroy(reqs->r_inputs); + } + + if(reqs->r_outputs) { + ADM_dataset_list_destroy(reqs->r_outputs); + } + + if(reqs->r_storage) { + ADM_storage_destroy(reqs->r_storage); + } + + free(reqs); + return ret; +} + +/** + * Initialize a job handle that can be used by clients to refer to a job. + * + * @remark This function is not actually part of the public API, but it is + * useful to have for internal purposes + * + * @param [in] id The identifier for this job + * @return A valid JOB HANDLE or NULL in case of failure. + */ +static ADM_job_t +ADM_job_create(uint64_t id) { + + struct adm_job* adm_job = (struct adm_job*) malloc(sizeof(struct adm_job)); + + if(!adm_job) { + LOGGER_ERROR("Could not allocate ADM_job_t") + return NULL; + } + + adm_job->j_id = id; + + return adm_job; +} + + +/******************************************************************************/ +/* C++ Type definitions and related functions */ +/******************************************************************************/ + +namespace admire { + +server::server(std::string protocol, std::string address) + : m_protocol(std::move(protocol)), m_address(std::move(address)) {} + +server::server(const ADM_server_t& srv) + : m_protocol(srv->s_protocol), m_address(srv->s_address) {} + +job::job(job_id id) : m_id(id) {} + +job::job(ADM_job_t job) : m_id(job->j_id) {} + +ADM_job_t +job::to_ctype() const { + return ADM_job_create(m_id); +} + +storage::storage(storage::type type, std::string id) + : m_id(std::move(id)), m_type(type) {} + +adhoc_storage::adhoc_storage(storage::type type, std::string id, + execution_mode exec_mode, access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, + bool should_flush) + : storage(type, std::move(id)), m_ctx{exec_mode, access_type, nodes, + walltime, should_flush} {} + +adhoc_storage::adhoc_storage(storage::type type, std::string id, + ADM_adhoc_context_t ctx) + : storage(type, std::move(id)), m_ctx(ctx) {} + +ADM_storage_t +adhoc_storage::to_rpc_type() const { + return ADM_storage_create(m_id.c_str(), + static_cast(m_type), + m_ctx.to_rpc_type()); +} + + +adhoc_storage::context::context(adhoc_storage::execution_mode exec_mode, + adhoc_storage::access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, + bool should_flush) + : m_exec_mode(exec_mode), m_access_type(access_type), m_nodes(nodes), + m_walltime(walltime), m_should_flush(should_flush) {} + +adhoc_storage::context::context(ADM_adhoc_context_t ctx) + : context(static_cast(ctx->c_mode), + static_cast(ctx->c_access), ctx->c_nodes, + ctx->c_walltime, ctx->c_should_bg_flush) {} + +ADM_adhoc_context_t +adhoc_storage::context::to_rpc_type() const { + return ADM_adhoc_context_create( + static_cast(m_exec_mode), + static_cast(m_access_type), m_nodes, m_walltime, + m_should_flush); +} + + +pfs_storage::pfs_storage(storage::type type, std::string id, + std::filesystem::path mount_point) + : storage(type, std::move(id)), m_ctx(std::move(mount_point)) {} + +pfs_storage::pfs_storage(storage::type type, std::string id, + ADM_pfs_context_t ctx) + : storage(type, std::move(id)), m_ctx(ctx) {} + +ADM_storage_t +pfs_storage::to_rpc_type() const { + return ADM_storage_create(m_id.c_str(), + static_cast(m_type), + m_ctx.to_rpc_type()); +} + + +pfs_storage::context::context(std::filesystem::path mount_point) + : m_mount_point(std::move(mount_point)) {} + +pfs_storage::context::context(ADM_pfs_context_t ctx) : context(ctx->c_mount) {} + +ADM_pfs_context_t +pfs_storage::context::to_rpc_type() const { + return ADM_pfs_context_create(m_mount_point.c_str()); +} + + +job_requirements::job_requirements(std::vector inputs, + std::vector outputs) + : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)) {} + +job_requirements::job_requirements(std::vector inputs, + std::vector outputs, + std::unique_ptr storage) + : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)), + m_storage(std::move(storage)) {} + +job_requirements::job_requirements(ADM_job_requirements_t reqs) { + m_inputs.reserve(reqs->r_inputs->l_length); + + for(size_t i = 0; i < reqs->r_inputs->l_length; ++i) { + m_inputs.emplace_back(reqs->r_inputs->l_datasets[i].d_id); + } + + m_outputs.reserve(reqs->r_outputs->l_length); + + for(size_t i = 0; i < reqs->r_outputs->l_length; ++i) { + m_outputs.emplace_back(reqs->r_outputs->l_datasets[i].d_id); + } + + if(reqs->r_storage) { + + switch(reqs->r_storage->s_type) { + + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + m_storage = std::make_unique( + static_cast(reqs->r_storage->s_type), + reqs->r_storage->s_id, &reqs->r_storage->s_adhoc_ctx); + break; + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + m_storage = std::make_unique( + static_cast(reqs->r_storage->s_type), + reqs->r_storage->s_id, &reqs->r_storage->s_pfs_ctx); + break; + } + } +} + +ADM_job_requirements_t +job_requirements::to_rpc_type() const { + using scord::utils::c_ptr; + using scord::utils::c_ptr_vector; + using dataset_vector = c_ptr_vector; + + dataset_vector inputs; + inputs.reserve(m_inputs.size()); + + for(const auto& in : m_inputs) { + inputs.emplace_back(ADM_dataset_create(in.m_id.c_str())); + } + + dataset_vector outputs; + outputs.reserve(m_outputs.size()); + + for(const auto& out : m_outputs) { + outputs.emplace_back(ADM_dataset_create(out.m_id.c_str())); + } + + return ADM_job_requirements_create( + inputs.data(), inputs.size(), outputs.data(), outputs.size(), + m_storage ? m_storage->to_rpc_type() : nullptr); +} + + +} // namespace admire diff --git a/src/scord-ctl/CMakeLists.txt b/src/scord-ctl/CMakeLists.txt index 26ea4e213caa71846416d948b35ae251cd1481ad..6d7c474b0f085fce8c0342f56dbd6ddd2e07c387 100644 --- a/src/scord-ctl/CMakeLists.txt +++ b/src/scord-ctl/CMakeLists.txt @@ -22,11 +22,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ -# import rpc definitions for scord-ctl -add_subdirectory(rpcs) - # scord-ctl daemon -add_executable(scord-ctl scord-ctl.cpp) +add_executable(scord-ctl) + +target_sources(scord-ctl PRIVATE scord-ctl.cpp rpc_handlers.hpp rpc_handlers.cpp) target_include_directories( scord-ctl @@ -36,7 +35,7 @@ target_include_directories( target_link_libraries( scord-ctl PRIVATE common::config common::logger common::network::rpc_server - scord_ctl_private_rpcs fmt::fmt Boost::program_options RedisPlusPlus::RedisPlusPlus + common::network::rpc_types admire_types fmt::fmt Boost::program_options ) install(TARGETS scord DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/scord/rpcs/private.cpp b/src/scord-ctl/rpc_handlers.cpp similarity index 95% rename from src/scord/rpcs/private.cpp rename to src/scord-ctl/rpc_handlers.cpp index d472d44ec0dab2230738f7799449a82e628c1411..74f349af3904ffe0f10a676fb0fb88f593043663 100644 --- a/src/scord/rpcs/private.cpp +++ b/src/scord-ctl/rpc_handlers.cpp @@ -23,7 +23,8 @@ *****************************************************************************/ #include -#include "private.hpp" +#include +#include "rpc_handlers.hpp" static void ADM_ping(hg_handle_t h) { diff --git a/src/scord/rpcs/private.hpp b/src/scord-ctl/rpc_handlers.hpp similarity index 86% rename from src/scord/rpcs/private.hpp rename to src/scord-ctl/rpc_handlers.hpp index 3af7df82cfa03fdc9c391de65758c7c53068b953..633befa25f9037682afec81a40568415ada80d40 100644 --- a/src/scord/rpcs/private.hpp +++ b/src/scord-ctl/rpc_handlers.hpp @@ -22,11 +22,19 @@ * SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ -#ifndef SCORD_RPCS_PRIVATE_HPP -#define SCORD_RPCS_PRIVATE_HPP +#ifndef SCORD_CTL_RPC_HANDLERS_HPP +#define SCORD_CTL_RPC_HANDLERS_HPP #include +#ifdef __cplusplus +extern "C" { +#endif + DECLARE_MARGO_RPC_HANDLER(ADM_ping); -#endif // SCORD_RPCS_PRIVATE_HPP +#ifdef __cplusplus +}; +#endif + +#endif // SCORD_CTL_RPC_HANDLERS_HPP diff --git a/src/scord-ctl/rpcs/private.cpp b/src/scord-ctl/rpcs/private.cpp deleted file mode 100644 index d472d44ec0dab2230738f7799449a82e628c1411..0000000000000000000000000000000000000000 --- a/src/scord-ctl/rpcs/private.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain - * - * This software was partially supported by the EuroHPC-funded project ADMIRE - * (Project ID: 956748, https://www.admire-eurohpc.eu). - * - * This file is part of scord. - * - * scord is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * scord is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with scord. If not, see . - * - * SPDX-License-Identifier: GPL-3.0-or-later - *****************************************************************************/ - -#include -#include "private.hpp" - -static void -ADM_ping(hg_handle_t h) { - - hg_return_t ret; - - [[maybe_unused]] margo_instance_id mid = margo_hg_handle_get_instance(h); - - LOGGER_INFO("PING(noargs)"); - - ret = margo_destroy(h); - assert(ret == HG_SUCCESS); -} - -DEFINE_MARGO_RPC_HANDLER(ADM_ping); diff --git a/src/scord-ctl/rpcs/private.hpp b/src/scord-ctl/rpcs/private.hpp deleted file mode 100644 index 6429eade640b78d47aaa91700c55359616102aaf..0000000000000000000000000000000000000000 --- a/src/scord-ctl/rpcs/private.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** - * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain - * - * This software was partially supported by the EuroHPC-funded project ADMIRE - * (Project ID: 956748, https://www.admire-eurohpc.eu). - * - * This file is part of scord. - * - * scord is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * scord is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with scord. If not, see . - * - * SPDX-License-Identifier: GPL-3.0-or-later - *****************************************************************************/ - -#ifndef SCORD_CTL_RPCS_PRIVATE_HPP -#define SCORD_CTL_RPCS_PRIVATE_HPP - -#include - -DECLARE_MARGO_RPC_HANDLER(ADM_ping); - -#endif // SCORD_CTL_RPCS_PRIVATE_HPP diff --git a/src/scord-ctl/scord-ctl.cpp b/src/scord-ctl/scord-ctl.cpp index b99caff9aff2180422a09250cddf095eabf694aa..834f25a176edc2013c90f6d60ccc1b5ecb897966 100644 --- a/src/scord-ctl/scord-ctl.cpp +++ b/src/scord-ctl/scord-ctl.cpp @@ -32,10 +32,10 @@ #include #include -#include +#include +#include #include -#include -#include "rpcs/private.hpp" +#include "rpc_handlers.hpp" namespace fs = std::filesystem; namespace bpo = boost::program_options; diff --git a/src/scord/CMakeLists.txt b/src/scord/CMakeLists.txt index aad2746c192ee9fc800ec9b2c058c21df4d8d8c4..e842d425012bba75ea627c3929a6f8bd67de74ec 100644 --- a/src/scord/CMakeLists.txt +++ b/src/scord/CMakeLists.txt @@ -22,35 +22,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ -################################################################################ -# Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain # -# # -# This software was partially supported by the EuroHPC-funded project ADMIRE # -# (Project ID: 956748, https://www.admire-eurohpc.eu). # -# # -# This file is part of scord. # -# # -# scord is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# scord is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with scord. If not, see . # -# # -# SPDX-License-Identifier: GPL-3.0-or-later # -################################################################################ - -# import rpc definitions for scord -add_subdirectory(rpcs) - # scord daemon -add_executable(scord scord.cpp) +add_executable(scord) + +target_sources(scord PRIVATE scord.cpp rpc_handlers.hpp rpc_handlers.cpp) target_include_directories( scord @@ -63,8 +38,8 @@ target_link_libraries( PRIVATE common::config common::logger common::network::rpc_server - api_rpcs - scord_private_rpcs + common::network::rpc_types + admire_types fmt::fmt Boost::program_options RedisPlusPlus::RedisPlusPlus diff --git a/src/lib/rpcs/public.cpp b/src/scord/rpc_handlers.cpp similarity index 95% rename from src/lib/rpcs/public.cpp rename to src/scord/rpc_handlers.cpp index e10b6587111882b49f63beac841ea7e17bcf5a7d..0e7b208d9429106745a664b7847deca665f45f47 100644 --- a/src/lib/rpcs/public.cpp +++ b/src/scord/rpc_handlers.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright 2021, Barcelona Supercomputing Center (BSC), Spain + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain * * This software was partially supported by the EuroHPC-funded project ADMIRE * (Project ID: 956748, https://www.admire-eurohpc.eu). @@ -22,12 +22,23 @@ * SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ -#include "public.hpp" +#include +#include +#include +#include "rpc_handlers.hpp" + +struct remote_procedure { + static std::uint64_t + new_id() { + static std::atomic_uint64_t current_id; + return current_id++; + } +}; static void ADM_ping(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; [[maybe_unused]] margo_instance_id mid = margo_hg_handle_get_instance(h); @@ -42,7 +53,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_ping); static void ADM_register_job(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_register_job_in_t in; ADM_register_job_out_t out; @@ -52,11 +63,14 @@ ADM_register_job(hg_handle_t h) { ret = margo_get_input(h, &in); assert(ret == HG_SUCCESS); - out.ret = -1; + const admire::job_requirements reqs(&in.reqs); - LOGGER_INFO("ADM_register_job()"); + const auto id = remote_procedure::new_id(); + LOGGER_INFO("RPC ID {} ({}): {{{}}}", id, __FUNCTION__, reqs); - out.ret = 0; + out.ret = ADM_SUCCESS; + + LOGGER_INFO("RPC ID {} ({}) = {}", id, __FUNCTION__, out.ret); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); @@ -74,7 +88,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_register_job); static void ADM_update_job(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_update_job_in_t in; ADM_update_job_out_t out; @@ -106,7 +120,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_update_job); static void ADM_remove_job(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_remove_job_in_t in; ADM_remove_job_out_t out; @@ -137,7 +151,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_remove_job); static void ADM_register_adhoc_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_register_adhoc_storage_in_t in; ADM_register_adhoc_storage_out_t out; @@ -168,7 +182,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_register_adhoc_storage); static void ADM_update_adhoc_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_update_adhoc_storage_in_t in; ADM_update_adhoc_storage_out_t out; @@ -199,7 +213,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_update_adhoc_storage); static void ADM_remove_adhoc_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_remove_adhoc_storage_in_t in; ADM_remove_adhoc_storage_out_t out; @@ -230,7 +244,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_remove_adhoc_storage); static void ADM_deploy_adhoc_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_deploy_adhoc_storage_in_t in; ADM_deploy_adhoc_storage_out_t out; @@ -261,7 +275,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_deploy_adhoc_storage); static void ADM_register_pfs_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_register_pfs_storage_in_t in; ADM_register_pfs_storage_out_t out; @@ -292,7 +306,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_register_pfs_storage); static void ADM_update_pfs_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_update_pfs_storage_in_t in; ADM_update_pfs_storage_out_t out; @@ -323,7 +337,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_update_pfs_storage); static void ADM_remove_pfs_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_remove_pfs_storage_in_t in; ADM_remove_pfs_storage_out_t out; @@ -363,7 +377,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_remove_pfs_storage); */ static void ADM_input(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_input_in_t in; ADM_input_out_t out; @@ -408,7 +423,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_input) */ static void ADM_output(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_output_in_t in; ADM_output_out_t out; @@ -453,7 +469,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_output) */ static void ADM_inout(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_inout_in_t in; ADM_inout_out_t out; @@ -507,7 +524,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_inout) */ static void ADM_adhoc_context(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_context_in_t in; ADM_adhoc_context_out_t out; @@ -561,7 +579,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_context) */ static void ADM_adhoc_context_id(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_context_id_in_t in; ADM_adhoc_context_id_out_t out; @@ -606,7 +625,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_context_id) */ static void ADM_adhoc_nodes(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_nodes_in_t in; ADM_adhoc_nodes_out_t out; @@ -654,7 +674,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_nodes) */ static void ADM_adhoc_walltime(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_walltime_in_t in; ADM_adhoc_walltime_out_t out; @@ -697,7 +718,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_walltime) */ static void ADM_adhoc_access(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_access_in_t in; ADM_adhoc_access_out_t out; @@ -750,7 +772,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_access) */ static void ADM_adhoc_distribution(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_distribution_in_t in; ADM_adhoc_distribution_out_t out; @@ -793,7 +816,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_distribution) */ static void ADM_adhoc_background_flush(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_background_flush_in_t in; ADM_adhoc_background_flush_out_t out; @@ -827,7 +851,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_background_flush) */ static void ADM_in_situ_ops(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_in_situ_ops_in_t in; ADM_in_situ_ops_out_t out; @@ -868,7 +893,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_in_situ_ops) */ static void ADM_in_transit_ops(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_in_transit_ops_in_t in; ADM_in_transit_ops_out_t out; @@ -925,7 +951,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_in_transit_ops) */ static void ADM_transfer_dataset(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_transfer_dataset_in_t in; ADM_transfer_dataset_out_t out; @@ -984,7 +1011,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_transfer_dataset) */ static void ADM_set_dataset_information(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_set_dataset_information_in_t in; ADM_set_dataset_information_out_t out; @@ -1039,7 +1067,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_set_dataset_information) */ static void ADM_set_io_resources(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_set_io_resources_in_t in; ADM_set_io_resources_out_t out; @@ -1090,7 +1119,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_set_io_resources) */ static void ADM_get_transfer_priority(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_get_transfer_priority_in_t in; ADM_get_transfer_priority_out_t out; @@ -1138,7 +1168,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_get_transfer_priority) */ static void ADM_set_transfer_priority(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_set_transfer_priority_in_t in; ADM_set_transfer_priority_out_t out; @@ -1185,7 +1216,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_set_transfer_priority) */ static void ADM_cancel_transfer(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_cancel_transfer_in_t in; ADM_cancel_transfer_out_t out; @@ -1229,7 +1261,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_cancel_transfer) */ static void ADM_get_pending_transfers(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_get_pending_transfers_in_t in; ADM_get_pending_transfers_out_t out; @@ -1272,7 +1305,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_get_pending_transfers) */ static void ADM_set_qos_constraints(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_set_qos_constraints_in_t in; ADM_set_qos_constraints_out_t out; @@ -1336,7 +1370,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_set_qos_constraints) */ static void ADM_get_qos_constraints(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_get_qos_constraints_in_t in; ADM_get_qos_constraints_out_t out; @@ -1398,7 +1433,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_get_qos_constraints) */ static void ADM_define_data_operation(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_define_data_operation_in_t in; ADM_define_data_operation_out_t out; @@ -1461,7 +1497,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_define_data_operation) */ static void ADM_connect_data_operation(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_connect_data_operation_in_t in; ADM_connect_data_operation_out_t out; @@ -1520,7 +1557,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_connect_data_operation) */ static void ADM_finalize_data_operation(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_finalize_data_operation_in_t in; ADM_finalize_data_operation_out_t out; @@ -1576,7 +1614,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_finalize_data_operation) */ static void ADM_link_transfer_to_data_operation(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_link_transfer_to_data_operation_in_t in; ADM_link_transfer_to_data_operation_out_t out; @@ -1638,7 +1677,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_link_transfer_to_data_operation) */ static void ADM_get_statistics(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_get_statistics_in_t in; ADM_get_statistics_out_t out; diff --git a/src/scord/rpc_handlers.hpp b/src/scord/rpc_handlers.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ee63174ee9c0b483a09c766bde1ef1fb8cfc9de0 --- /dev/null +++ b/src/scord/rpc_handlers.hpp @@ -0,0 +1,159 @@ +/****************************************************************************** + * Copyright 2021, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + +// clang-format off +#ifndef SCORD_RPC_HANDLERS_HPP +#define SCORD_RPC_HANDLERS_HPP + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// FIXME: cannot be in a namespace due to Margo limitations +// namespace scord::network::rpc { + +/// ADM_ping +DECLARE_MARGO_RPC_HANDLER(ADM_ping); + +/// ADM_register_job +DECLARE_MARGO_RPC_HANDLER(ADM_register_job); + +/// ADM_update_job +DECLARE_MARGO_RPC_HANDLER(ADM_update_job); + +/// ADM_remove_job +DECLARE_MARGO_RPC_HANDLER(ADM_remove_job); + +/// ADM_register_adhoc_storage +DECLARE_MARGO_RPC_HANDLER(ADM_register_adhoc_storage); + +/// ADM_update_adhoc_storage +DECLARE_MARGO_RPC_HANDLER(ADM_update_adhoc_storage); + +/// ADM_remove_adhoc_storage +DECLARE_MARGO_RPC_HANDLER(ADM_remove_adhoc_storage); + +/// ADM_deploy_adhoc_storage +DECLARE_MARGO_RPC_HANDLER(ADM_deploy_adhoc_storage); + +/// ADM_register_pfs_storage +DECLARE_MARGO_RPC_HANDLER(ADM_register_pfs_storage); + +/// ADM_update_pfs_storage +DECLARE_MARGO_RPC_HANDLER(ADM_update_pfs_storage); + +/// ADM_remove_pfs_storage +DECLARE_MARGO_RPC_HANDLER(ADM_remove_pfs_storage); + +/// ADM_input +DECLARE_MARGO_RPC_HANDLER(ADM_input); + +/// ADM_output +DECLARE_MARGO_RPC_HANDLER(ADM_output); + +/// ADM_inout +DECLARE_MARGO_RPC_HANDLER(ADM_inout); + +/// ADM_adhoc_context +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_context); + +/// ADM_adhoc_context_id +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_context_id); + +/// ADM_adhoc_nodes +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_nodes) + +/// ADM_adhoc_walltime +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_walltime); + + +/// ADM_adhoc_access +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_access); + +/// ADM_adhoc_distribution +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_distribution); + +/// ADM_adhoc_background_flush +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_background_flush); + +/// ADM_in_situ_ops +DECLARE_MARGO_RPC_HANDLER(ADM_in_situ_ops); + +/// ADM_in_transit_ops +DECLARE_MARGO_RPC_HANDLER(ADM_in_transit_ops); + + +/// ADM_transfer_dataset +DECLARE_MARGO_RPC_HANDLER(ADM_transfer_dataset); + +/// ADM_set_dataset_information +DECLARE_MARGO_RPC_HANDLER(ADM_set_dataset_information); + +/// ADM_set_io_resources +DECLARE_MARGO_RPC_HANDLER(ADM_set_io_resources); + +/// ADM_get_transfer_priority +DECLARE_MARGO_RPC_HANDLER(ADM_get_transfer_priority); + +/// ADM_set_transfer_priority +DECLARE_MARGO_RPC_HANDLER(ADM_set_transfer_priority); + +/// ADM_cancel_transfer +DECLARE_MARGO_RPC_HANDLER(ADM_cancel_transfer); + +/// ADM_get_pending_transfers +DECLARE_MARGO_RPC_HANDLER(ADM_get_pending_transfers); + +/// ADM_set_qos_constraints +DECLARE_MARGO_RPC_HANDLER(ADM_set_qos_constraints); + +/// ADM_get_qos_constraints +DECLARE_MARGO_RPC_HANDLER(ADM_get_qos_constraints); + +/// ADM_define_data_operation +DECLARE_MARGO_RPC_HANDLER(ADM_define_data_operation); + +/// ADM_connect_data_operation +DECLARE_MARGO_RPC_HANDLER(ADM_connect_data_operation); + +/// ADM_finalize_data_operation +DECLARE_MARGO_RPC_HANDLER(ADM_finalize_data_operation); + +/// ADM_link_transfer_to_data_operation +DECLARE_MARGO_RPC_HANDLER(ADM_link_transfer_to_data_operation); + +/// ADM_get_statistics +DECLARE_MARGO_RPC_HANDLER(ADM_get_statistics); + + +//} // namespace scord::network::rpc + +#ifdef __cplusplus +}; +#endif + +#endif // SCORD_RPC_HANDLERS_HPP +// clang-format on diff --git a/src/scord/rpcs/CMakeLists.txt b/src/scord/rpcs/CMakeLists.txt deleted file mode 100644 index 38b0acf513f7b63de7ec76dc2e59d86999062793..0000000000000000000000000000000000000000 --- a/src/scord/rpcs/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -################################################################################ -# Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain # -# # -# This software was partially supported by the EuroHPC-funded project ADMIRE # -# (Project ID: 956748, https://www.admire-eurohpc.eu). # -# # -# This file is part of scord. # -# # -# scord is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# scord is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with scord. If not, see . # -# # -# SPDX-License-Identifier: GPL-3.0-or-later # -################################################################################ - -add_library(scord_ctl_private_rpcs STATIC) -target_sources(scord_ctl_private_rpcs - PRIVATE private.cpp private.hpp) - -target_include_directories(scord_ctl_private_rpcs INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(scord_ctl_private_rpcs PUBLIC common::logger Margo::Margo) -set_property(TARGET scord_ctl_private_rpcs PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/scord/scord.cpp b/src/scord/scord.cpp index 1d07fd506ae26ea6702614e090ca7ee0139ec84c..48c3d6d6431113a90598c4e06d51f49ae6985dbb 100644 --- a/src/scord/scord.cpp +++ b/src/scord/scord.cpp @@ -32,10 +32,10 @@ #include #include -#include +#include +#include #include -#include -#include "rpcs/private.hpp" +#include "rpc_handlers.hpp" namespace fs = std::filesystem; namespace bpo = boost::program_options;