diff --git a/examples/c/ADM_register_job.c b/examples/c/ADM_register_job.c index b1b9926ce6ae3be533b9114463c9fbd55554515b..7c53dceb0b9eebc065d054427f22fdd9d70d3259 100644 --- a/examples/c/ADM_register_job.c +++ b/examples/c/ADM_register_job.c @@ -1,5 +1,6 @@ #include #include +#include #include #define NINPUTS 10 @@ -8,7 +9,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); @@ -17,14 +18,13 @@ main(int argc, char* argv[]) { int exit_status = EXIT_SUCCESS; ADM_server_t server = ADM_server_create("tcp", argv[1]); - ADM_job_t job; ADM_dataset_t inputs[NINPUTS]; 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,22 @@ 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); + assert(ctx); + + ADM_storage_t st = ADM_storage_create("foobar", ADM_STORAGE_GEKKOFS, ctx); + assert(st); + + ADM_job_requirements_t reqs = + ADM_job_requirements_create(inputs, NINPUTS, outputs, NOUTPUTS, st); + assert(reqs); + ADM_return_t ret = ADM_register_job(server, reqs, &job); if(ret != ADM_SUCCESS) { @@ -54,7 +63,6 @@ main(int argc, char* argv[]) { "successfully\n"); cleanup: - for(int i = 0; i < NINPUTS; ++i) { ADM_dataset_destroy(inputs[i]); } @@ -63,6 +71,12 @@ cleanup: ADM_dataset_destroy(outputs[i]); } + ADM_storage_destroy(st); + + ADM_adhoc_context_destroy(ctx); + + ADM_job_requirements_destroy(reqs); + ADM_server_destroy(server); exit(exit_status); } diff --git a/examples/cxx/ADM_register_job.cpp b/examples/cxx/ADM_register_job.cpp index 5001058b58cbb77d501d289af7159028a26c7bb8..cd31c15c307454e797adf0f56bddf498df19109b 100644 --- a/examples/cxx/ADM_register_job.cpp +++ b/examples/cxx/ADM_register_job.cpp @@ -1,22 +1,40 @@ #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)); + } - try { + std::vector outputs; + outputs.reserve(NOUTPUTS); + for(int i = 0; i < NOUTPUTS; ++i) { + outputs.emplace_back(fmt::format("output-dataset-{}", i)); + } + auto p = std::make_unique( + admire::storage::type::gekkofs, "foobar", + admire::adhoc_storage::execution_mode::separate_new, + admire::adhoc_storage::access_type::read_write, 42, 100, false); + + admire::job_requirements reqs(inputs, outputs, std::move(p)); + + try { [[maybe_unused]] const auto job = admire::register_job(server, reqs); // do something with job diff --git a/examples/cxx/ADM_remove_job.cpp b/examples/cxx/ADM_remove_job.cpp index fc037a10e8f6b7f34adec1e400515c7cbc858aba..55261e99e8caf0c64c97894e3fd7e74a0d6adbc9 100644 --- a/examples/cxx/ADM_remove_job.cpp +++ b/examples/cxx/ADM_remove_job.cpp @@ -5,30 +5,24 @@ int main(int argc, char* argv[]) { - if(argc != 3) { - fmt::print(stderr, "ERROR: no location provided\n"); - fmt::print(stderr, "Usage: ADM_remove_job \n"); + if(argc != 2) { + fmt::print(stderr, "ERROR: no server address provided\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); + [[maybe_unused]] const auto ret = admire::remove_job(server, job); + 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); - } - - if(ret != ADM_SUCCESS) { fmt::print(stdout, "ADM_remove_job() remote procedure not completed " "successfully\n"); 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..a82a2dae19ca2929d17abc866b8ddadbf1461cc9 100644 --- a/examples/cxx/ADM_update_job.cpp +++ b/examples/cxx/ADM_update_job.cpp @@ -1,20 +1,39 @@ #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{}; + 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)); + } + + auto p = std::make_unique( + admire::storage::type::gekkofs, "foobar", + admire::adhoc_storage::execution_mode::separate_new, + admire::adhoc_storage::access_type::read_write, 42, 100, false); + + admire::job job{42}; + admire::job_requirements reqs{inputs, outputs, std::move(p)}; ADM_return_t ret = ADM_SUCCESS; try { 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..d23339e39029b8f3b60b2baceb48983acd7818eb --- /dev/null +++ b/src/common/net/proto/rpc_types.c @@ -0,0 +1,426 @@ +/****************************************************************************** + * 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_job_t(hg_proc_t proc, void* data) { + + hg_return_t ret = HG_SUCCESS; + ADM_job_t* job = (ADM_job_t*) data; + ADM_job_t tmp = NULL; + hg_size_t job_length = 0; + + switch(hg_proc_get_op(proc)) { + + case HG_ENCODE: + // find out the length of the adm_storage object we need to send + job_length = *job ? sizeof(adm_job) : 0; + ret = hg_proc_hg_size_t(proc, &job_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!job_length) { + return HG_SUCCESS; + } + + // if we actually need to send an adm_job object, + // write it to the mercury buffer + tmp = *job; + + ret = hg_proc_adm_job(proc, tmp); + + if(ret != HG_SUCCESS) { + break; + } + + break; + + case HG_DECODE: + // find out the length of the adm_storage object + ret = hg_proc_hg_size_t(proc, &job_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!job_length) { + *job = NULL; + break; + } + + // if the received adm_job object was not NULL, read each of + // its fields from the mercury buffer + tmp = (adm_job*) calloc(1, sizeof(adm_job)); + + ret = hg_proc_adm_job(proc, tmp); + + if(ret != HG_SUCCESS) { + break; + } + + // return the newly-created ctx + *job = tmp; + break; + + case HG_FREE: + tmp = *job; + free(tmp); + break; + } + + return ret; +} + +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_t(proc, &tmp->s_adhoc_ctx); + break; + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + ret = hg_proc_ADM_pfs_context_t(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_t(proc, &tmp->s_adhoc_ctx); + break; + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + ret = hg_proc_ADM_pfs_context_t(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; +} + +hg_return_t +hg_proc_ADM_pfs_context_t(hg_proc_t proc, void* data) { + + hg_return_t ret = HG_SUCCESS; + ADM_pfs_context_t* ctx = (ADM_pfs_context_t*) data; + ADM_pfs_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_pfs_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_pfs_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_pfs_context_t) calloc(1, sizeof(struct adm_pfs_context)); + ret = hg_proc_adm_pfs_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 62% rename from src/lib/rpcs/public.hpp rename to src/common/net/proto/rpc_types.h index 5e03eef0ba5afdf4a21eb94a37cd8a09c8faedd3..2e1139f01591aeb2db9c48aa7f58be370e5d6296 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,291 @@ * 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 -// FIXME: cannot be in a namespace due to Margo limitations -// namespace scord::network::rpc { +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus -/// ADM_ping -DECLARE_MARGO_RPC_HANDLER(ADM_ping); +/** + * 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 + */ -/// ADM_register_job -MERCURY_GEN_PROC(ADM_register_job_in_t, ((int32_t) (reqs))) +typedef struct adm_node { + const char* n_hostname; +} adm_node; -MERCURY_GEN_PROC(ADM_register_job_out_t, ((int32_t) (ret))) +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_node, // NOLINT + ((hg_const_string_t) (n_hostname)) +); +// clang-format on -DECLARE_MARGO_RPC_HANDLER(ADM_register_job); +typedef struct adm_dataset { + const char* d_id; +} adm_dataset; -/// ADM_update_job -MERCURY_GEN_PROC(ADM_update_job_in_t, ((int32_t) (reqs))) +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_dataset, // NOLINT + ((hg_const_string_t) (d_id)) +); +// clang-format on -MERCURY_GEN_PROC(ADM_update_job_out_t, ((int32_t) (ret))) +typedef struct adm_job { + uint64_t j_id; +} adm_job; -DECLARE_MARGO_RPC_HANDLER(ADM_update_job); +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_job, // NOLINT + ((hg_uint64_t) (j_id)) +); +// clang-format on -/// ADM_remove_job -MERCURY_GEN_PROC(ADM_remove_job_in_t, ((int32_t) (reqs))) +hg_return_t +hg_proc_ADM_job_t(hg_proc_t proc, void* data); + +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_t s_adhoc_ctx; + ADM_pfs_context_t 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; +}; + +hg_return_t +hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data); + +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 -MERCURY_GEN_PROC(ADM_remove_job_out_t, ((int32_t) (ret))) +// clang-format off + +/// ADM_register_job +MERCURY_GEN_PROC( + ADM_register_job_in_t, + ((adm_job_requirements) (reqs)) +); -DECLARE_MARGO_RPC_HANDLER(ADM_remove_job); +MERCURY_GEN_PROC( + ADM_register_job_out_t, + ((int32_t) (retval)) + ((ADM_job_t) (job)) +); + +/// ADM_update_job +MERCURY_GEN_PROC( + ADM_update_job_in_t, + ((ADM_job_t) (job)) + ((adm_job_requirements) (reqs)) +); + +MERCURY_GEN_PROC( + ADM_update_job_out_t, + ((int32_t) (retval)) +); + +/// ADM_remove_job +MERCURY_GEN_PROC( + ADM_remove_job_in_t, + ((ADM_job_t) (job)) +); + +MERCURY_GEN_PROC( + ADM_remove_job_out_t, + ((int32_t) (retval)) +); /// 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 +314,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 +321,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 +328,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 +353,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 +360,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 +390,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 +399,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 +408,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 +415,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 +423,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 +430,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 +437,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 +447,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 +455,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 +464,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 +475,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 +483,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 +493,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 +501,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..c183f0125bde74c50f31393118b00cb41403a2e7 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 ctype_ptr.hpp) diff --git a/src/common/utils/ctype_ptr.hpp b/src/common/utils/ctype_ptr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..830e6da80767840de569ed09a9e88be1cc5c4190 --- /dev/null +++ b/src/common/utils/ctype_ptr.hpp @@ -0,0 +1,96 @@ +/****************************************************************************** + * 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 ctype_ptr = + std::unique_ptr::type, + deleter::type, fn>>; + +// 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 ctype_ptr_vector { + + ctype_ptr_vector() = default; + + ~ctype_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* + 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..a80305100d8405ca280d3be2d913f42254f059bb 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 - PRIVATE admire.cpp c_wrapper.cpp detail/impl.hpp detail/impl.cpp errors.c) + 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 types.cpp) 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..76c294766ca1ed1ca0b3db1f3290e7beba53c65e 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); @@ -201,54 +196,13 @@ register_job(const server& srv, ADM_job_requirements_t reqs) { } 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; - - endp.call("ADM_update_job", &in, &out); - - if(out.ret < 0) { - LOGGER_ERROR("ADM_update_job() = {}", out.ret); - return static_cast(out.ret); - } - - LOGGER_INFO("ADM_update_job() = {}", ADM_SUCCESS); - return ADM_SUCCESS; +update_job(const server& srv, const job& job, const job_requirements& reqs) { + return detail::update_job(srv, job, reqs); } 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; - - endp.call("ADM_remove_job", &in, &out); - - if(out.ret < 0) { - LOGGER_ERROR("ADM_remove_job() = {}", out.ret); - return static_cast(out.ret); - } - - LOGGER_INFO("ADM_remove_job() = {}", ADM_SUCCESS); - return ADM_SUCCESS; +remove_job(const server& srv, const job& job) { + return detail::remove_job(srv, job); } ADM_return_t @@ -259,9 +213,9 @@ register_adhoc_storage(const server& srv, ADM_job_t job, (void) ctx; (void) adhoc_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_register_adhoc_storage(...)"); @@ -287,9 +241,9 @@ update_adhoc_storage(const server& srv, ADM_job_t job, ADM_adhoc_context_t ctx, (void) ctx; (void) adhoc_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_update_adhoc_storage(...)"); @@ -314,9 +268,9 @@ remove_adhoc_storage(const server& srv, ADM_job_t job, (void) job; (void) adhoc_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_remove_adhoc_storage(...)"); @@ -341,9 +295,9 @@ deploy_adhoc_storage(const server& srv, ADM_job_t job, (void) job; (void) adhoc_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_deploy_adhoc_storage(...)"); @@ -369,9 +323,9 @@ register_pfs_storage(const server& srv, ADM_job_t job, ADM_pfs_context_t ctx, (void) ctx; (void) pfs_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_register_pfs_storage(...)"); @@ -397,9 +351,9 @@ update_pfs_storage(const server& srv, ADM_job_t job, ADM_pfs_context_t ctx, (void) ctx; (void) pfs_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_update_pfs_storage(...)"); @@ -424,9 +378,9 @@ remove_pfs_storage(const server& srv, ADM_job_t job, (void) job; (void) pfs_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_remove_pfs_storage(...)"); @@ -456,9 +410,9 @@ transfer_dataset(const server& srv, ADM_job_t job, ADM_dataset_t** sources, (void) mapping; (void) transfer; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_transfer_dataset(...)"); @@ -484,9 +438,9 @@ set_dataset_information(const server& srv, ADM_job_t job, ADM_dataset_t target, (void) target; (void) info; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_set_dataset_information(...)"); @@ -512,9 +466,9 @@ set_io_resources(const server& srv, ADM_job_t job, ADM_storage_t tier, (void) tier; (void) resources; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_set_io_resources(...)"); @@ -540,9 +494,9 @@ get_transfer_priority(const server& srv, ADM_job_t job, ADM_transfer_t transfer, (void) transfer; (void) priority; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_get_transfer_priority(...)"); @@ -568,9 +522,9 @@ set_transfer_priority(const server& srv, ADM_job_t job, ADM_transfer_t transfer, (void) transfer; (void) incr; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_set_transfer_priority(...)"); @@ -594,9 +548,9 @@ cancel_transfer(const server& srv, ADM_job_t job, ADM_transfer_t transfer) { (void) job; (void) transfer; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_cancel_transfer(...)"); @@ -622,9 +576,9 @@ get_pending_transfers(const server& srv, ADM_job_t job, (void) job; (void) pending_transfers; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_get_pending_transfers(...)"); @@ -651,9 +605,9 @@ set_qos_constraints(const server& srv, ADM_job_t job, ADM_qos_entity_t entity, (void) entity; (void) limit; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_set_qos_constraints(...)"); @@ -680,9 +634,9 @@ get_qos_constraints(const server& srv, ADM_job_t job, ADM_qos_entity_t entity, (void) entity; (void) limits; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_get_qos_constraints(...)"); @@ -710,9 +664,9 @@ define_data_operation(const server& srv, ADM_job_t job, const char* path, (void) op; (void) args; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_define_data_operation(...)"); @@ -741,9 +695,9 @@ connect_data_operation(const server& srv, ADM_job_t job, ADM_dataset_t input, (void) should_stream; (void) args; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_connect_data_operation(...)"); @@ -771,9 +725,9 @@ finalize_data_operation(const server& srv, ADM_job_t job, (void) op; (void) status; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_finalize_data_operation(...)"); @@ -802,9 +756,9 @@ link_transfer_to_data_operation(const server& srv, ADM_job_t job, (void) should_stream; (void) args; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_link_transfer_to_data_operation(...)"); @@ -829,9 +783,9 @@ get_statistics(const server& srv, ADM_job_t job, ADM_job_stats_t** stats) { (void) job; (void) stats; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_get_statistics(...)"); 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..9aacc72a4dcc1f29351736faec1d7aee35bb2ffb 100644 --- a/src/lib/admire.hpp +++ b/src/lib/admire.hpp @@ -23,37 +23,38 @@ *****************************************************************************/ #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); +update_job(const server& srv, const job&, const job_requirements& reqs); ADM_return_t -remove_job(const server& srv, ADM_job_t job); +remove_job(const server& srv, const job& job); ADM_return_t register_adhoc_storage(const server& srv, ADM_job_t job, 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..16b9525e8a3767af61943cf4a33906334434d01c --- /dev/null +++ b/src/lib/admire_types.hpp @@ -0,0 +1,692 @@ +/****************************************************************************** + * 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 +#include "admire_types.h" + +namespace admire { + +using error_code = ADM_return_t; + +using job_id = std::uint64_t; + +struct server { + + server(std::string protocol, std::string address); + explicit server(const ADM_server_t& srv); + server(server&&) noexcept; + server& + operator=(server&&) noexcept; + ~server(); + + std::string + protocol() const; + std::string + address() const; + +private: + class impl; + std::unique_ptr m_pimpl; +}; + +struct job { + + explicit job(job_id id); + explicit job(ADM_job_t job); + job(const job&) noexcept; + job(job&&) noexcept; + job& + operator=(job&&) noexcept; + job& + operator=(const job&) noexcept; + ~job(); + + job_id + id() const; + +private: + class impl; + std::unique_ptr m_pimpl; +}; + +struct dataset { + explicit dataset(std::string id); + explicit dataset(ADM_dataset_t dataset); + dataset(const dataset&) noexcept; + dataset(dataset&&) noexcept; + dataset& + operator=(const dataset&) noexcept; + dataset& + operator=(dataset&&) noexcept; + ~dataset(); + + std::string + id() const; + +private: + class impl; + std::unique_ptr m_pimpl; +}; + +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 + }; + + struct ctx { + virtual ~ctx() = default; + }; + + storage(storage::type type, std::string id); + + virtual ~storage() = default; + + std::string + id() const; + type + type() const; + + virtual std::shared_ptr + context() const = 0; + +protected: + std::string m_id; + enum 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 ctx : storage::ctx { + + ctx(execution_mode exec_mode, access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, bool should_flush); + + explicit ctx(ADM_adhoc_context_t ctx); + + execution_mode + exec_mode() const; + enum access_type + access_type() const; + std::uint32_t + nodes() const; + std::uint32_t + walltime() const; + bool + should_flush() const; + + private: + execution_mode m_exec_mode; + enum access_type m_access_type; + std::uint32_t m_nodes; + std::uint32_t m_walltime; + bool m_should_flush; + }; + + adhoc_storage(enum 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(enum storage::type type, std::string id, + ADM_adhoc_context_t ctx); + adhoc_storage(adhoc_storage&&) noexcept = default; + adhoc_storage& + operator=(adhoc_storage&&) noexcept = default; + ~adhoc_storage() override; + + std::shared_ptr + context() const final; + +private: + class impl; + std::unique_ptr m_pimpl; +}; + +struct pfs_storage : public storage { + + struct ctx : storage::ctx { + + explicit ctx(std::filesystem::path mount_point); + + explicit ctx(ADM_pfs_context_t ctx); + + std::filesystem::path + mount_point() const; + + private: + std::filesystem::path m_mount_point; + }; + + pfs_storage(enum storage::type type, std::string id, + std::filesystem::path mount_point); + pfs_storage(enum storage::type type, std::string id, ADM_pfs_context_t ctx); + pfs_storage(pfs_storage&&) noexcept = default; + pfs_storage& + operator=(pfs_storage&&) noexcept = default; + ~pfs_storage() override; + + std::shared_ptr + context() const final; + +private: + class impl; + std::unique_ptr m_pimpl; +}; + +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); + + job_requirements(const job_requirements&) noexcept; + job_requirements(job_requirements&&) noexcept; + job_requirements& + operator=(const job_requirements&) noexcept; + job_requirements& + operator=(job_requirements&&) noexcept; + + ~job_requirements(); + + std::vector + inputs() const; + std::vector + outputs() const; + std::shared_ptr + storage() const; + +private: + class impl; + std::unique_ptr m_pimpl; +}; + +template +struct managed_rpc_type; + +template +struct unmanaged_rpc_type; + +} // namespace admire + + +//////////////////////////////////////////////////////////////////////////////// +// Specializations for conversion types +//////////////////////////////////////////////////////////////////////////////// + +template <> +struct admire::managed_rpc_type { + + template + using managed_ptr = scord::utils::ctype_ptr; + + explicit managed_rpc_type(const admire::adhoc_storage::ctx& ctx) + : m_adhoc_context(ADM_adhoc_context_create( + static_cast(ctx.exec_mode()), + static_cast(ctx.access_type()), + ctx.nodes(), ctx.walltime(), ctx.should_flush())) {} + + ADM_adhoc_context_t + get() const { + return m_adhoc_context.get(); + } + + managed_ptr m_adhoc_context; +}; + + +template <> +struct admire::managed_rpc_type { + + template + using rpc_storage_ptr = scord::utils::ctype_ptr; + + template + using managed_ptr = scord::utils::ctype_ptr; + + explicit managed_rpc_type(const admire::adhoc_storage& st) + : m_adhoc_context(*std::static_pointer_cast( + st.context())), + m_storage(ADM_storage_create( + st.id().c_str(), static_cast(st.type()), + m_adhoc_context.get())) {} + + ADM_storage_t + get() const { + return m_storage.get(); + } + + managed_rpc_type m_adhoc_context; + rpc_storage_ptr m_storage; +}; + +template <> +struct admire::managed_rpc_type> { + + template + using managed_ptr_vector = scord::utils::ctype_ptr_vector; + + explicit managed_rpc_type(const std::vector& datasets) { + m_datasets.reserve(datasets.size()); + + for(const auto& d : datasets) { + m_datasets.emplace_back(ADM_dataset_create(d.id().c_str())); + } + } + + const ADM_dataset_t* + data() const { + return m_datasets.data(); + } + + ADM_dataset_t* + data() { + return m_datasets.data(); + } + + std::size_t + size() const { + return m_datasets.size(); + } + + managed_ptr_vector m_datasets; +}; + +template <> +struct admire::managed_rpc_type { + + template + using rpc_requirements_ptr = scord::utils::ctype_ptr; + + explicit managed_rpc_type(const admire::job_requirements& reqs) + : m_inputs(reqs.inputs()), m_outputs(reqs.outputs()), + m_storage(*std::dynamic_pointer_cast( + reqs.storage())), + m_reqs(ADM_job_requirements_create(m_inputs.data(), m_inputs.size(), + m_outputs.data(), m_outputs.size(), + m_storage.get())) {} + + ADM_job_requirements_t + get() const { + return m_reqs.get(); + } + + managed_rpc_type> m_inputs; + managed_rpc_type> m_outputs; + managed_rpc_type m_storage; + rpc_requirements_ptr + m_reqs; +}; + +// forward declarations +ADM_job_t +ADM_job_create(uint64_t id); +ADM_return_t +ADM_job_destroy(ADM_job_t job); + +template <> +struct admire::managed_rpc_type { + + template + using rpc_job_ptr = scord::utils::ctype_ptr; + + explicit managed_rpc_type(const admire::job& j) + : m_job(ADM_job_create(j.id())) {} + + ADM_job_t + get() const { + return m_job.get(); + } + + rpc_job_ptr m_job; +}; + +template <> +struct admire::managed_rpc_type { + + template + using rpc_job_ptr = scord::utils::ctype_ptr; + + explicit managed_rpc_type(ADM_job_t job) : m_job(job) {} + + admire::job + get() const { + return admire::job(m_job.get()); + } + + rpc_job_ptr m_job; +}; + +template <> +struct admire::unmanaged_rpc_type { + + explicit unmanaged_rpc_type(const admire::job& j) + : m_job(ADM_job_create(j.id())) {} + + ADM_job_t + get() const { + return m_job; + } + + ADM_job_t m_job; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Formatting functions +//////////////////////////////////////////////////////////////////////////////// + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::error_code& ec, FormatContext& ctx) const { + std::string_view name = "unknown"; + + switch(ec) { + case ADM_SUCCESS: + name = "ADM_SUCCESS"; + break; + case ADM_ESNAFU: + name = "ADM_ESNAFU"; + break; + case ADM_EBADARGS: + name = "ADM_EBADARGS"; + break; + case ADM_ENOMEM: + name = "ADM_ENOMEM"; + break; + case ADM_EOTHER: + name = "ADM_EOTHER"; + break; + default: + break; + } + + return formatter::format(name, ctx); + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::job& j, FormatContext& ctx) const { + return formatter::format( + fmt::format("id: {}", j.id()), ctx); + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::dataset& d, FormatContext& ctx) const { + return formatter::format("\"" + d.id() + "\"", ctx); + } +}; + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const enum 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::shared_ptr& s, + FormatContext& ctx) const { + + if(!s) { + return formatter::format("NULL", ctx); + } + + switch(s->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 pctx = std::dynamic_pointer_cast( + s.context()); + + const auto str = + fmt::format("{{type: {}, id: {}, context: {}}}", s.type(), + std::quoted(s.id()), + (pctx ? fmt::format("{}", *pctx) : "NULL")); + return formatter::format(str, ctx); + } +}; + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::adhoc_storage::ctx& c, FormatContext& ctx) const { + + const auto str = + fmt::format("{{execution_mode: {}, access_type: {}, " + "nodes: {}, walltime: {}, should_flush: {}}}", + c.exec_mode(), c.access_type(), c.nodes(), + c.walltime(), c.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 pctx = std::dynamic_pointer_cast( + s.context()); + const auto str = fmt::format( + "{{context: {}}}", (pctx ? fmt::format("{}", *pctx) : "NULL")); + return formatter::format(str, ctx); + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::pfs_storage::ctx& c, FormatContext& ctx) const { + const auto str = fmt::format("{{mount_point: {}}}", c.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.inputs(), ", "), + fmt::join(r.outputs(), ", "), r.storage()), + ctx); + } +}; + +#endif // SCORD_ADMIRE_TYPES_HPP diff --git a/src/lib/c_wrapper.cpp b/src/lib/c_wrapper.cpp index 6cf1747f4428da23c289833158b361bdd25c1d85..d0cdacf36766ef310929cdb7378695a94f812b42 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::unmanaged_rpc_type{*rv}.get(); return ADM_SUCCESS; } @@ -604,17 +63,18 @@ 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); + return admire::update_job(srv, admire::job{job}, + admire::job_requirements{reqs}); } 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); + return admire::remove_job(srv, admire::job{job}); } ADM_return_t @@ -622,7 +82,7 @@ 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}; return admire::register_adhoc_storage(srv, job, ctx, adhoc_storage); } @@ -631,7 +91,7 @@ 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 +100,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 +109,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 +118,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 +127,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 +136,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 +147,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 +157,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 +166,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 +176,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 +185,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 +194,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 +203,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 +212,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 +221,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 +230,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 +245,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 +261,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 +271,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 +285,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..b6e7d15a40d48098ee72da2c3a02112ce38bcbd7 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 { @@ -155,9 +150,9 @@ namespace admire::detail { admire::error_code ping(const server& srv) { - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_ping()"); endp.call("ADM_ping"); @@ -167,28 +162,91 @@ ping(const server& srv) { } 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) { - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); - LOGGER_INFO("ADM_register_job(...)"); + LOGGER_INFO("RPC (ADM_{}) => {{job_requirements: {{{}}}}}", __FUNCTION__, + reqs); - ADM_register_job_in_t in{}; + auto rpc_reqs = managed_rpc_type{reqs}; + + ADM_register_job_in_t in{*rpc_reqs.get()}; ADM_register_job_out_t out; endp.call("ADM_register_job", &in, &out); - if(out.ret < 0) { - LOGGER_ERROR("ADM_register_job() = {}", out.ret); - return tl::make_unexpected(static_cast(out.ret)); + if(out.retval < 0) { + LOGGER_ERROR("RPC (ADM_{}) <= {}", __FUNCTION__, out.retval); + return tl::make_unexpected(static_cast(out.retval)); } - LOGGER_INFO("ADM_register_job() = {}", ADM_SUCCESS); - return admire::job{42}; + const auto rpc_job = managed_rpc_type{out.job}; + const admire::job job = rpc_job.get(); + + LOGGER_INFO("RPC (ADM_{}) <= {{retval: {}, job: {{{}}}}}", __FUNCTION__, + ADM_SUCCESS, job.id()); + + return job; +} + +admire::error_code +update_job(const server& srv, const job& job, const job_requirements& reqs) { + + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; + + auto endp = rpc_client.lookup(srv.address()); + + LOGGER_INFO("RPC ({}): {{job: {{{}}}, job_requirements: {{{}}}}}", + "ADM_update_job", job, reqs); + + const auto rpc_job = managed_rpc_type{job}; + const auto rpc_reqs = managed_rpc_type{reqs}; + + ADM_update_job_in_t in{rpc_job.get(), *rpc_reqs.get()}; + ADM_update_job_out_t out; + + endp.call("ADM_update_job", &in, &out); + + + if(out.retval < 0) { + const auto retval = static_cast(out.retval); + LOGGER_ERROR("RPC (ADM_{}) <= {{retval: {}}}", __FUNCTION__, + retval); + return retval; + } + + LOGGER_INFO("RPC (ADM_{}) <= {{retval: {}}}", __FUNCTION__, ADM_SUCCESS); + return ADM_SUCCESS; +} + +admire::error_code +remove_job(const server& srv, const job& job) { + + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; + + auto endp = rpc_client.lookup(srv.address()); + + LOGGER_INFO("RPC (ADM_{}) => {{job: {}}}", __FUNCTION__, job); + + const auto rpc_job = managed_rpc_type{job}; + + ADM_remove_job_in_t in{rpc_job.get()}; + ADM_remove_job_out_t out; + + endp.call("ADM_remove_job", &in, &out); + + if(out.retval < 0) { + const auto retval = static_cast(out.retval); + LOGGER_ERROR("RPC (ADM_{}) <= {{retval: {}}}", __FUNCTION__, + retval); +return retval; + } + + LOGGER_INFO("RPC (ADM_{}) <= {{retval: {}}}", __FUNCTION__, ADM_SUCCESS); + return ADM_SUCCESS; } } // namespace admire::detail diff --git a/src/lib/detail/impl.hpp b/src/lib/detail/impl.hpp index cacc056ff3572e735014d77a21472acd3cd18079..a047192b77149e2c19dd8a0d3ed5bc16aeaf44cd 100644 --- a/src/lib/detail/impl.hpp +++ b/src/lib/detail/impl.hpp @@ -27,10 +27,7 @@ #define SCORD_ADMIRE_IMPL_HPP #include - -namespace admire { -using error_code = ADM_return_t; -} // namespace admire +#include namespace admire::detail { @@ -38,7 +35,13 @@ 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); + +admire::error_code +update_job(const server& srv, const job& job, const job_requirements& reqs); + +admire::error_code +remove_job(const server& srv, const job& job); } // namespace admire::detail diff --git a/src/lib/types.cpp b/src/lib/types.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9be36b09e1f53ee7ea0c62663578206f20af0803 --- /dev/null +++ b/src/lib/types.cpp @@ -0,0 +1,1106 @@ +/****************************************************************************** + * 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)); + const char* error_msg = NULL; + + 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 = (const char*) calloc(strlen(id) + 1, sizeof(char)); + strcpy((char*) 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) calloc(1, sizeof(adm_adhoc_context)); + if(!adm_storage->s_adhoc_ctx) { + error_msg = "Could not allocate ADM_adhoc_context_t"; + goto cleanup_on_error; + } + + memcpy(adm_storage->s_adhoc_ctx, (ADM_adhoc_context_t) ctx, + sizeof(*(ADM_adhoc_context_t) ctx)); + break; + + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + adm_storage->s_pfs_ctx = + (ADM_pfs_context_t) calloc(1, sizeof(adm_pfs_context)); + if(!adm_storage->s_pfs_ctx) { + error_msg = "Could not allocate ADM_pfs_context_t"; + goto cleanup_on_error; + } + + memcpy(adm_storage->s_pfs_ctx, (ADM_pfs_context_t) ctx, + sizeof(*(ADM_pfs_context_t) ctx)); + break; + } + + return adm_storage; + +cleanup_on_error: + if(error_msg) { + LOGGER_ERROR(error_msg); + } + + [[maybe_unused]] ADM_return_t ret = ADM_storage_destroy(adm_storage); + assert(ret); + + return NULL; +} + +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; + } + + if(storage->s_id) { + free((void*) storage->s_id); + } + + switch(storage->s_type) { + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + if(storage->s_adhoc_ctx) { + free(storage->s_adhoc_ctx); + } + break; + + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + if(storage->s_pfs_ctx) { + free(storage->s_pfs_ctx); + } + break; + } + + 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*) calloc( + 1, 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; + + 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 type"; + goto cleanup_on_error; + } + + adm_job_reqs->r_storage = ADM_storage_create(storage->s_id, storage->s_type, + storage->s_adhoc_ctx); + + return adm_job_reqs; + +cleanup_on_error: + + if(error_msg) { + LOGGER_ERROR(error_msg); + } + + if(adm_job_reqs) { + ADM_job_requirements_destroy(adm_job_reqs); + } + + 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. + */ +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; +} + +/** + * Destroy a ADM_job_t created by ADM_job_create(). + * + * @remark This function is not actually part of the public API, but it is + * useful to have for internal purposes + * + * @param[in] reqs The ADM_job_t to destroy. + * @return ADM_SUCCESS or corresponding error code. + */ +ADM_return_t +ADM_job_destroy(ADM_job_t job) { + ADM_return_t ret = ADM_SUCCESS; + + if(!job) { + LOGGER_ERROR("Invalid ADM_job_t") + return ADM_EBADARGS; + } + + free(job); + return ret; +} + + +/******************************************************************************/ +/* C++ Type definitions and related functions */ +/******************************************************************************/ + +namespace admire { + +class server::impl { + +public: + impl(std::string protocol, std::string address) + : m_protocol(std::move(protocol)), m_address(std::move(address)) {} + + std::string + protocol() const { + return m_protocol; + } + + std::string + address() const { + return m_address; + } + +private: + std::string m_protocol; + std::string m_address; +}; + +server::server(std::string protocol, std::string address) + : m_pimpl(std::make_unique(std::move(protocol), + std::move(address))) {} + +server::server(const ADM_server_t& srv) + : server::server(srv->s_protocol, srv->s_address) {} + +server::server(server&&) noexcept = default; + +server& +server::operator=(server&&) noexcept = default; + +server::~server() = default; + +std::string +server::protocol() const { + return m_pimpl->protocol(); +} + +std::string +server::address() const { + return m_pimpl->address(); +} + + +class job::impl { + +public: + explicit impl(job_id id) : m_id(id) {} + + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; + + job_id + id() const { + return m_id; + } + +private: + job_id m_id; +}; + +job::job(job_id id) : m_pimpl(std::make_unique(id)) {} + +job::job(ADM_job_t job) : job::job(job->j_id) {} + +job::job(job&&) noexcept = default; + +job& +job::operator=(job&&) noexcept = default; + +job::job(const job& other) noexcept + : m_pimpl(std::make_unique(*other.m_pimpl)) {} + +job& +job::operator=(const job& other) noexcept { + this->m_pimpl = std::make_unique(*other.m_pimpl); + return *this; +} + +job::~job() = default; + +job_id +job::id() const { + return m_pimpl->id(); +} + +class dataset::impl { +public: + explicit impl(std::string id) : m_id(std::move(id)) {} + + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; + ~impl() = default; + + std::string + id() const { + return m_id; + } + +private: + std::string m_id; +}; + +dataset::dataset(std::string id) + : m_pimpl(std::make_unique(std::move(id))) {} + +dataset::dataset(ADM_dataset_t dataset) : dataset::dataset(dataset->d_id) {} + +dataset::dataset(const dataset& other) noexcept + : m_pimpl(std::make_unique(*other.m_pimpl)) {} + +dataset::dataset(dataset&&) noexcept = default; + +dataset& +dataset::operator=(const dataset& other) noexcept { + this->m_pimpl = std::make_unique(*other.m_pimpl); + return *this; +} + +dataset& +dataset::operator=(dataset&&) noexcept = default; + +dataset::~dataset() = default; + +std::string +dataset::id() const { + return m_pimpl->id(); +} + + +storage::storage(enum storage::type type, std::string id) + : m_id(std::move(id)), m_type(type) {} + +std::string +storage::id() const { + return m_id; +} + +enum storage::type +storage::type() const { + return m_type; +} + +adhoc_storage::ctx::ctx(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::ctx::ctx(ADM_adhoc_context_t ctx) + : adhoc_storage::ctx(static_cast(ctx->c_mode), + static_cast(ctx->c_access), + ctx->c_nodes, ctx->c_walltime, + ctx->c_should_bg_flush) {} + +adhoc_storage::execution_mode +adhoc_storage::ctx::exec_mode() const { + return m_exec_mode; +} + +adhoc_storage::access_type +adhoc_storage::ctx::access_type() const { + return m_access_type; +} + +std::uint32_t +adhoc_storage::ctx::nodes() const { + return m_nodes; +} + +std::uint32_t +adhoc_storage::ctx::walltime() const { + return m_walltime; +} + +bool +adhoc_storage::ctx::should_flush() const { + return m_should_flush; +} + +class adhoc_storage::impl { + +public: + explicit impl(adhoc_storage::ctx ctx) : m_ctx(std::move(ctx)) {} + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; + + adhoc_storage::ctx + context() const { + return m_ctx; + } + +private: + adhoc_storage::ctx m_ctx; +}; + + +adhoc_storage::adhoc_storage(enum 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_pimpl(std::make_unique(adhoc_storage::ctx{ + exec_mode, access_type, nodes, walltime, should_flush})) {} + +adhoc_storage::adhoc_storage(enum storage::type type, std::string id, + ADM_adhoc_context_t ctx) + : storage(type, std::move(id)), + m_pimpl(std::make_unique(adhoc_storage::ctx{ctx})) {} + +std::shared_ptr +adhoc_storage::context() const { + return std::make_shared(m_pimpl->context()); +} + +adhoc_storage::~adhoc_storage() = default; + +pfs_storage::ctx::ctx(std::filesystem::path mount_point) + : m_mount_point(std::move(mount_point)) {} + +pfs_storage::ctx::ctx(ADM_pfs_context_t ctx) : pfs_storage::ctx(ctx->c_mount) {} + +std::filesystem::path +pfs_storage::ctx::mount_point() const { + return m_mount_point; +} + +class pfs_storage::impl { + +public: + explicit impl(pfs_storage::ctx ctx) : m_ctx(std::move(ctx)) {} + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; + + pfs_storage::ctx + context() const { + return m_ctx; + } + +private: + pfs_storage::ctx m_ctx; +}; + +pfs_storage::pfs_storage(enum storage::type type, std::string id, + std::filesystem::path mount_point) + : storage(type, std::move(id)), + m_pimpl(std::make_unique( + pfs_storage::ctx{std::move(mount_point)})) {} + +pfs_storage::pfs_storage(enum storage::type type, std::string id, + ADM_pfs_context_t ctx) + : storage(type, std::move(id)), + m_pimpl(std::make_unique(pfs_storage::ctx{ctx})) {} + +pfs_storage::~pfs_storage() = default; + +std::shared_ptr +pfs_storage::context() const { + return std::make_shared(m_pimpl->context()); +} + +class job_requirements::impl { + +public: + impl(std::vector inputs, + std::vector outputs) + : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)) {} + + impl(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)) {} + + explicit impl(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; + } + } + } + + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; + + std::vector + inputs() const { + return m_inputs; + } + + std::vector + outputs() const { + return m_outputs; + } + + std::shared_ptr + storage() const { + return m_storage; + } + +private: + std::vector m_inputs; + std::vector m_outputs; + std::shared_ptr m_storage; +}; + + +job_requirements::job_requirements(std::vector inputs, + std::vector outputs) + : m_pimpl(std::make_unique(std::move(inputs), std::move(outputs))) {} + +job_requirements::job_requirements(std::vector inputs, + std::vector outputs, + std::unique_ptr storage) + : m_pimpl(std::make_unique(std::move(inputs), std::move(outputs), + std::move(storage))) {} + +job_requirements::job_requirements(ADM_job_requirements_t reqs) + : m_pimpl(std::make_unique(reqs)) {} + +job_requirements::job_requirements(const job_requirements& other) noexcept + : m_pimpl(std::make_unique(*other.m_pimpl)) {} + +job_requirements::job_requirements(job_requirements&&) noexcept = default; + +job_requirements& +job_requirements::operator=(const job_requirements& other) noexcept { + this->m_pimpl = std::make_unique(*other.m_pimpl); + return *this; +} + +job_requirements& +job_requirements::operator=(job_requirements&&) noexcept = default; + +job_requirements::~job_requirements() = default; + +std::vector +job_requirements::inputs() const { + return m_pimpl->inputs(); +} + +std::vector +job_requirements::outputs() const { + return m_pimpl->outputs(); +} + +std::shared_ptr +job_requirements::storage() const { + return m_pimpl->storage(); +} + + +} // 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 93% rename from src/lib/rpcs/public.cpp rename to src/scord/rpc_handlers.cpp index e10b6587111882b49f63beac841ea7e17bcf5a7d..68677cc805cdaf7478ab19bccb27458b4987ff53 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,22 @@ 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 {} ({}) <= {{job_requirements: {{{}}}}}", id, + __FUNCTION__, reqs); - out.ret = 0; + const auto job = admire::job{42}; + + const auto rpc_job = admire::unmanaged_rpc_type{job}; + admire::error_code rv = ADM_SUCCESS; + + out.retval = rv; + out.job = rpc_job.get(); + + LOGGER_INFO("RPC ID {} ({}) => {{retval: {}, job: {{{}}}}}", id, + __FUNCTION__, rv, job); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); @@ -74,7 +96,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; @@ -84,11 +106,17 @@ ADM_update_job(hg_handle_t h) { ret = margo_get_input(h, &in); assert(ret == HG_SUCCESS); - out.ret = -1; + const admire::job job(in.job); + const admire::job_requirements reqs(&in.reqs); - LOGGER_INFO("ADM_update_job()"); + const auto id = remote_procedure::new_id(); + LOGGER_INFO("RPC ID {} ({}) <= {{job: {{{}}}, job_requirements: {{{}}}}}", + id, __FUNCTION__, job, reqs); - out.ret = 0; + admire::error_code rv = ADM_SUCCESS; + out.retval = rv; + + LOGGER_INFO("RPC ID {} ({}) => {{retval: {}}}", id, __FUNCTION__, rv); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); @@ -106,7 +134,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; @@ -116,11 +144,15 @@ ADM_remove_job(hg_handle_t h) { ret = margo_get_input(h, &in); assert(ret == HG_SUCCESS); - out.ret = -1; + const admire::job job(in.job); - LOGGER_INFO("ADM_remove_job()"); + const auto id = remote_procedure::new_id(); + LOGGER_INFO("RPC ID {} ({}) <= {{job: {{{}}}", id, __FUNCTION__, job); - out.ret = 0; + admire::error_code rv = ADM_SUCCESS; + out.retval = rv; + + LOGGER_INFO("RPC ID {} ({}) => {{retval: {}}}", id, __FUNCTION__, rv); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); @@ -137,7 +169,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 +200,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 +231,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 +262,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 +293,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 +324,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 +355,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 +395,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 +441,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 +487,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 +542,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 +597,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 +643,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 +692,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 +736,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 +790,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 +834,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 +869,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 +911,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 +969,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 +1029,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 +1085,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 +1137,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 +1186,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 +1234,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 +1279,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 +1323,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 +1388,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 +1451,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 +1515,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 +1575,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 +1632,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 +1695,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;