Commit b63c5aa1 authored by Matthieu Dorier's avatar Matthieu Dorier
Browse files

Merge branch 'dev-bedrock-26' into 'master'

Bedrock bindings and json configuration

See merge request !19
parents c0677770 ca8a206d
...@@ -7,7 +7,7 @@ distversion: ...@@ -7,7 +7,7 @@ distversion:
# #
# Easy way to build unit tests without running them # Easy way to build unit tests without running them
# #
.phony: tests .phony: tests
tests: $(check_PROGRAMS) tests: $(check_PROGRAMS)
...@@ -6,7 +6,7 @@ bin_SCRIPTS = ...@@ -6,7 +6,7 @@ bin_SCRIPTS =
noinst_PROGRAMS = noinst_PROGRAMS =
noinst_HEADERS = noinst_HEADERS =
TESTS = TESTS =
XFAIL_TESTS = XFAIL_TESTS =
check_PROGRAMS = check_PROGRAMS =
EXTRA_PROGRAMS = EXTRA_PROGRAMS =
CLEANFILES = $(bin_SCRIPTS) CLEANFILES = $(bin_SCRIPTS)
...@@ -23,7 +23,7 @@ include_HEADERS = include/bake.h\ ...@@ -23,7 +23,7 @@ include_HEADERS = include/bake.h\
TESTS_ENVIRONMENT = TESTS_ENVIRONMENT =
EXTRA_DIST += \ EXTRA_DIST += \
prepare.sh prepare.sh
AM_CPPFLAGS = -I$(top_srcdir)/include AM_CPPFLAGS = -I$(top_srcdir)/include
...@@ -36,6 +36,10 @@ AM_CXXFLAGS = $(AM_CFLAGS) ...@@ -36,6 +36,10 @@ AM_CXXFLAGS = $(AM_CFLAGS)
lib_LTLIBRARIES = src/libbake-client.la src/libbake-server.la lib_LTLIBRARIES = src/libbake-client.la src/libbake-server.la
src_libbake_client_la_SOURCES = src_libbake_client_la_SOURCES =
src_libbake_server_la_SOURCES = src_libbake_server_la_SOURCES =
if ENABLE_BEDROCK
lib_LTLIBRARIES += src/libbake-bedrock.la
src_libbake_bedrock_la_SOURCES =
endif
LDADD = src/libbake-client.la src/libbake-server.la LDADD = src/libbake-client.la src/libbake-server.la
......
...@@ -86,6 +86,12 @@ LIBS="$UUID_LIBS $LIBS" ...@@ -86,6 +86,12 @@ LIBS="$UUID_LIBS $LIBS"
CPPFLAGS="$UUID_CFLAGS $CPPFLAGS" CPPFLAGS="$UUID_CFLAGS $CPPFLAGS"
CFLAGS="$UUID_CFLAGS $CFLAGS" CFLAGS="$UUID_CFLAGS $CFLAGS"
PKG_CHECK_MODULES([JSONC],[json-c],[],
[AC_MSG_ERROR([Could not find working json-c installation!])])
LIBS="$JSONC_LIBS $LIBS"
CPPFLAGS="$JSONC_CFLAGS $CPPFLAGS"
CFLAGS="$JSONC_CFLAGS $CFLAGS"
AC_ARG_ENABLE(remi, AC_ARG_ENABLE(remi,
[AS_HELP_STRING([--enable-remi],[Enable REMI (migration) support @<:@default=no@:>@])], [AS_HELP_STRING([--enable-remi],[Enable REMI (migration) support @<:@default=no@:>@])],
[case "${enableval}" in [case "${enableval}" in
...@@ -111,6 +117,27 @@ fi ...@@ -111,6 +117,27 @@ fi
AC_SUBST(USE_REMI) AC_SUBST(USE_REMI)
AC_SUBST(REMI_PKG) AC_SUBST(REMI_PKG)
AC_ARG_ENABLE(bedrock,
[AS_HELP_STRING([--enable-bedrock],[Enable bedrock library support @<:@default=no@:>@])],
[case "${enableval}" in
yes) enable_bedrock="yes" ;;
no) enable_bedrock="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-bedrock) ;;
esac],
[enable_bedrock="no"]
)
AM_CONDITIONAL(ENABLE_BEDROCK, test x$enable_bedrock = xyes)
if test "$enable_bedrock" = "yes"; then
PKG_CHECK_MODULES(BEDROCK, bedrock-server)
AC_DEFINE(USE_BEDROCK, 1, [BEDROCK support enabled.])
USE_BEDROCK=1
CPPFLAGS="$BEDROCK_CFLAGS $CPPFLAGS"
CFLAGS="$BEDROCK_CFLAGS $CFLAGS"
else
USE_BEDROCK=0
fi
AC_SUBST(USE_BEDROCK)
AC_ARG_ENABLE(benchmark, AC_ARG_ENABLE(benchmark,
[AS_HELP_STRING([--enable-benchmark],[Build Bake benchmark @<:@default=no@:>@])], [AS_HELP_STRING([--enable-benchmark],[Build Bake benchmark @<:@default=no@:>@])],
[case "${enableval}" in [case "${enableval}" in
......
{
"margo" : {
"argobots": {
"pools" : [
{
"name" : "io_pool"
}
],
"xstreams" : [
{
"name" : "io1",
"scheduler" : {
"type" : "basic_wait",
"pools" : [ "io_pool" ]
}
},
{
"name" : "io2",
"scheduler" : {
"type" : "basic_wait",
"pools" : [ "io_pool" ]
}
},
{
"name" : "io3",
"scheduler" : {
"type" : "basic_wait",
"pools" : [ "io_pool" ]
}
},
{
"name" : "io4",
"scheduler" : {
"type" : "basic_wait",
"pools" : [ "io_pool" ]
}
}
]
}
},
"abt_io" : [
{
"name" : "bake_abt_io",
"pool" : "io_pool"
}
],
"libraries" : {
"bake" : "libbake-bedrock.so"
},
"providers" : [
{
"name" : "my_bake_provider",
"type" : "bake",
"provider_id" : 1,
"pool" : "__primary__",
"config" : {
"pipeline_enable":true,
"pipeline_npools":4,
"pipeline_nbuffers_per_pool":32,
"pipeline_first_buffer_size":65536,
"pipeline_multiplier":4,
"file_backend":{
"targets":[
"./file-target-A.dat"
],
"alignment":4096
},
"pmem_backend":{
"targets":[
"./pmem-target-A.dat"
]
}
},
"dependencies" : {
"abt_io" : "bake_abt_io"
}
}
]
}
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#ifndef __BAKE_SERVER_H #ifndef __BAKE_SERVER_H
#define __BAKE_SERVER_H #define __BAKE_SERVER_H
#include <abt-io.h>
#include <margo.h> #include <margo.h>
#include <libpmemobj.h> #include <libpmemobj.h>
#include <bake.h> #include <bake.h>
...@@ -15,24 +16,28 @@ ...@@ -15,24 +16,28 @@
extern "C" { extern "C" {
#endif #endif
#define BAKE_ABT_POOL_DEFAULT ABT_POOL_NULL
#define BAKE_PROVIDER_ID_DEFAULT 0 #define BAKE_PROVIDER_ID_DEFAULT 0
#define BAKE_PROVIDER_IGNORE NULL #define BAKE_PROVIDER_IGNORE NULL
typedef struct bake_provider* bake_provider_t; typedef struct bake_provider* bake_provider_t;
/** /**
* Creates a BAKE pool to use for backend PMEM storage. * The bake_provider_init_info structure can be passed in to the
* * bake_provider_register() function to configure the provider. The struct
* NOTE: This function must be called on a pool before the pool * can be memset to zero to use default values.
* can be passed to 'bake_provider_register'.
*
* @param[in] pool_name path to PMEM backend file
* @param[in] pool_size size of the created pool
* @param[in] pool_mode mode of the created pool
* @returns 0 on success, -1 otherwise
*/ */
int bake_makepool(const char* pool_name, size_t pool_size, mode_t pool_mode); struct bake_provider_init_info {
const char* json_config; /* optional JSON-formatted string */
ABT_pool rpc_pool; /* optional pool on which to run RPC handlers */
abt_io_instance_id aid; /* optional abt-io instance, used by file backend */
void* remi_provider; /* optional REMI provider */
void* remi_client; /* optional REMI client */
};
#define BAKE_PROVIDER_INIT_INFO_INITIALIZER \
{ \
NULL, ABT_POOL_NULL, ABT_IO_INSTANCE_NULL, NULL, NULL \
}
/** /**
* Initializes a BAKE provider. * Initializes a BAKE provider.
...@@ -44,35 +49,49 @@ int bake_makepool(const char* pool_name, size_t pool_size, mode_t pool_mode); ...@@ -44,35 +49,49 @@ int bake_makepool(const char* pool_name, size_t pool_size, mode_t pool_mode);
* @param[out] provider resulting provider * @param[out] provider resulting provider
* @returns 0 on success, -1 otherwise * @returns 0 on success, -1 otherwise
*/ */
int bake_provider_register(margo_instance_id mid, int bake_provider_register(margo_instance_id mid,
uint16_t provider_id, uint16_t provider_id,
ABT_pool pool, const struct bake_provider_init_info* args,
bake_provider_t* provider); bake_provider_t* provider);
/** /**
* @brief Deregisters and destroys the provider. * @brief Deregisters the provider.
* *
* @param provider Provider to deregister and destroy. * @param provider Provider to deregister.
* *
* @return 0 on success, -1 otherwise. * @return 0 on success, -1 otherwise.
*/ */
int bake_provider_destroy(bake_provider_t provider); int bake_provider_deregister(bake_provider_t provider);
/** /**
* Makes the provider start managing a target. * Makes the provider start managing a target. The target must have already
* The target must have been previously created with bake_makepool, * been created in the past.
* and it should not be managed by another provider (whether in this
* proccess or another).
* *
* @param provider Bake provider * @param provider Bake provider
* @param target_name path to pmem target * @param target_name path to pmem target
* @param target_id resulting id identifying the target * @param target_id resulting id identifying the target
* *
* @return 0 on success, -1 on failure * @return BAKE_SUCCESS or BAKE_ERR*
*/
int bake_provider_attach_target(bake_provider_t provider,
const char* target_name,
bake_target_id_t* target_id);
/**
* Create a new target that did not yet exist and begin managing it.
*
* @param provider Bake provider
* @param target_name path to pmem target
* @param[in] size size of the created target (may be ignored for target
* types that can be extended or use a fixed size physical device)
* @param target_id resulting id identifying the target
*
* @return BAKE_SUCCESS or BAKE_ERR*
*/ */
int bake_provider_add_storage_target(bake_provider_t provider, int bake_provider_create_target(bake_provider_t provider,
const char* target_name, const char* target_name,
bake_target_id_t* target_id); size_t size,
bake_target_id_t* target_id);
/** /**
* Makes the provider stop managing a target. * Makes the provider stop managing a target.
...@@ -82,8 +101,8 @@ int bake_provider_add_storage_target(bake_provider_t provider, ...@@ -82,8 +101,8 @@ int bake_provider_add_storage_target(bake_provider_t provider,
* *
* @return 0 on success, -1 on failure * @return 0 on success, -1 on failure
*/ */
int bake_provider_remove_storage_target(bake_provider_t provider, int bake_provider_detach_target(bake_provider_t provider,
bake_target_id_t target_id); bake_target_id_t target_id);
/** /**
* Removes all the targets associated with a provider. * Removes all the targets associated with a provider.
...@@ -92,7 +111,7 @@ int bake_provider_remove_storage_target(bake_provider_t provider, ...@@ -92,7 +111,7 @@ int bake_provider_remove_storage_target(bake_provider_t provider,
* *
* @return 0 on success, -1 on failure * @return 0 on success, -1 on failure
*/ */
int bake_provider_remove_all_storage_targets(bake_provider_t provider); int bake_provider_detach_all_targets(bake_provider_t provider);
/** /**
* Returns the number of targets that this provider manages. * Returns the number of targets that this provider manages.
...@@ -102,13 +121,13 @@ int bake_provider_remove_all_storage_targets(bake_provider_t provider); ...@@ -102,13 +121,13 @@ int bake_provider_remove_all_storage_targets(bake_provider_t provider);
* *
* @return 0 on success, -1 on failure * @return 0 on success, -1 on failure
*/ */
int bake_provider_count_storage_targets(bake_provider_t provider, int bake_provider_count_targets(bake_provider_t provider,
uint64_t* num_targets); uint64_t* num_targets);
/** /**
* List the target ids of the targets managed by this provider. * List the target ids of the targets managed by this provider.
* The targets array must be pre-allocated with at least enough * The targets array must be pre-allocated with at least enough
* space to hold all the targets (use bake_provider_count_storage_targets * space to hold all the targets (use bake_provider_count_targets
* to know how many storage targets are managed). * to know how many storage targets are managed).
* *
* @param provider Bake provider * @param provider Bake provider
...@@ -116,41 +135,29 @@ int bake_provider_count_storage_targets(bake_provider_t provider, ...@@ -116,41 +135,29 @@ int bake_provider_count_storage_targets(bake_provider_t provider,
* *
* @return 0 on success, -1 on failure * @return 0 on success, -1 on failure
*/ */
int bake_provider_list_storage_targets(bake_provider_t provider, int bake_provider_list_targets(bake_provider_t provider,
bake_target_id_t* targets); bake_target_id_t* targets);
/* TODO: the following configuration management functions would ideally be
* split off into a dedicated component. Treating this as a prototype for
* now.
*/
/** /**
* @brief Set configuration parameters as string key/value pairs * Retrieves complete configuration of bake provider, encoded as json
*
* @param provider Bake provider
* @param key Configuration key
* @param value Configuratiion value
* *
* @return 0 on success, -1 on failure * @param [in] provider bake provider
* @returns null terminated string that must be free'd by caller
*/ */
int bake_provider_set_conf(bake_provider_t provider, char* bake_provider_get_config(bake_provider_t provider);
const char* key,
const char* value);
/** /**
* @brief Set configuration parameters for a target. * Creates a raw storage target, not connected to a provider. This would
* mainly be used by external utilities, not a server daemon itself.
* *
* @param provider Bake provider * @param[in] path path to storage target (could be a file, directory, or
* @param tid Bake target id * device depending on the backend type)
* @param key Configuration key * @param[in] size size of the created target (may be ignored for target
* @param value Configuration value * types that can be extended or use a fixed size physical device)
* *
* @return 0 on success, -1 on failure * @returns 0 on success, -1 otherwise
*/ */
int bake_target_set_conf(bake_provider_t provider, int bake_create_raw_target(const char* path, size_t size);
bake_target_id_t tid,
const char* key,
const char* value);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
/* /*
* (C) 2019 The University of Chicago * (C) 2019 The University of Chicago
* *
* See COPYRIGHT in top-level directory. * See COPYRIGHT in top-level directory.
*/ */
#ifndef __BAKE_SERVER_HPP #ifndef __BAKE_SERVER_HPP
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <bake-server.h> #include <bake-server.h>
#define _CHECK_RET(__ret) \ #define _CHECK_RET(__ret) \
if(__ret != BAKE_SUCCESS) throw exception(__ret) if (__ret != BAKE_SUCCESS) throw exception(__ret)
namespace bake { namespace bake {
...@@ -23,11 +23,9 @@ namespace bake { ...@@ -23,11 +23,9 @@ namespace bake {
* @param pool_size Pool size. * @param pool_size Pool size.
* @param pool_mode Mode. * @param pool_mode Mode.
*/ */
inline void makepool( inline void create_raw_target(const std::string& path, size_t size)
const std::string& pool_name, {
size_t pool_size, int ret = bake_create_raw_target(path.c_str(), size);
mode_t pool_mode) {
int ret = bake_makepool(pool_name.c_str(), pool_size, pool_mode);
_CHECK_RET(ret); _CHECK_RET(ret);
} }
...@@ -36,39 +34,68 @@ inline void makepool( ...@@ -36,39 +34,68 @@ inline void makepool(
*/ */
class provider { class provider {
margo_instance_id m_mid = MARGO_INSTANCE_NULL; margo_instance_id m_mid = MARGO_INSTANCE_NULL;
bake_provider_t m_provider = NULL; bake_provider_t m_provider = NULL;
provider( provider(margo_instance_id mid,
margo_instance_id mid, uint16_t provider_id,
uint16_t provider_id = 0, const bake_provider_init_info* args)
ABT_pool pool = ABT_POOL_NULL) : m_mid(mid)
: m_mid(mid) { {
int ret = bake_provider_register(mid, provider_id, pool, &m_provider); int ret = bake_provider_register(mid, provider_id, args, &m_provider);
_CHECK_RET(ret); _CHECK_RET(ret);
} }
static void finalize_callback(void* args) { static void finalize_callback(void* args)
{
auto* p = static_cast<provider*>(args); auto* p = static_cast<provider*>(args);
delete p; delete p;
} }
public: public:
/** /**
* @brief Factory method to create an instance of provider. * @brief Factory method to create an instance of provider.
* *
* @param mid Margo instance id. * @param mid Margo instance id.
* @param provider_id Provider id. * @param provider_id Provider id.
* @param pool Argobots pool. * @param pool Argobots pool.
* @param config JSON config.
* @param abtid ABT-IO instance.
* @param remi REMI provider.
*
* @return Pointer to newly created provider.
*/
static provider* create(margo_instance_id mid,
uint16_t provider_id = 0,
ABT_pool pool = ABT_POOL_NULL,
const std::string& config = "",
abt_io_instance_id abtio = ABT_IO_INSTANCE_NULL,
void* remi_provider = NULL,
void* remi_client = NULL)
{
bake_provider_init_info args = BAKE_PROVIDER_INIT_INFO_INITIALIZER;
args.json_config = config.c_str();
args.rpc_pool = pool;
args.aid = abtio;
args.remi_provider = remi_provider;
args.remi_client = remi_client;
return create(mid, provider_id, &args);
}
/**
* @brief Factory method to create an instance of provider.
*
* @param mid Margo instance id.
* @param provider_id Provider id.
* @param args bake_provider_init_info structure.
* *
* @return Pointer to newly created provider. * @return Pointer to newly created provider.
*/ */
static provider* create(margo_instance_id mid, static provider* create(margo_instance_id mid,
uint16_t provider_id = 0, uint16_t provider_id,
ABT_pool pool = BAKE_ABT_POOL_DEFAULT) { const bake_provider_init_info* args = nullptr)
auto p = new provider(mid, provider_id, pool); {
auto p = new provider(mid, provider_id, args);
margo_provider_push_finalize_callback(mid, p, &finalize_callback, p); margo_provider_push_finalize_callback(mid, p, &finalize_callback, p);
return p; return p;
} }
...@@ -96,9 +123,10 @@ class provider { ...@@ -96,9 +123,10 @@ class provider {
/** /**
* @brief Destructor. * @brief Destructor.
*/ */
~provider() { ~provider()
{
margo_provider_pop_finalize_callback(m_mid, this); margo_provider_pop_finalize_callback(m_mid, this);
bake_provider_destroy(m_provider); bake_provider_deregister(m_provider);
} }
/** /**
...@@ -109,12 +137,28 @@ class provider { ...@@ -109,12 +137,28 @@ class provider {
* *
* @return a target object. * @return a target object.
*/ */
target add_storage_target(const std::string& target_name) { target attach_target(const std::string& target_name)
{
target t; target t;
int ret = bake_provider_add_storage_target( int ret = bake_provider_attach_target(m_provider, target_name.c_str(),
m_provider, &(t.m_tid));
target_name.c_str(), _CHECK_RET(ret);
&(t.m_tid)); return t;
}
/**
* @brief Create a storage target and attach it to the provider.
*
* @param target_name Path to the target.
* @param size Target size.
*
* @return a target object.
*/
target create_target(const std::string& target_name, size_t size)
{