#ifndef LIBPMEMOBJ_CTL_INTERNAL_H
#define LIBPMEMOBJ_CTL_INTERNAL_H 1
#include "libpmemobj.h"
#include "queue.h"
struct ctl;
struct ctl_index {
const char *name;
long value;
SLIST_ENTRY(ctl_index) entry;
};
SLIST_HEAD(ctl_indexes, ctl_index);
enum ctl_query_source {
CTL_UNKNOWN_QUERY_SOURCE,
CTL_QUERY_PROGRAMMATIC,
CTL_QUERY_CONFIG_INPUT,
MAX_CTL_QUERY_SOURCE
};
enum ctl_query_type {
CTL_QUERY_READ,
CTL_QUERY_WRITE,
CTL_QUERY_RUNNABLE,
MAX_CTL_QUERY_TYPE
};
typedef int (*node_callback)(PMEMobjpool *pop, enum ctl_query_source type,
void *arg, struct ctl_indexes *indexes);
enum ctl_node_type {
CTL_NODE_UNKNOWN,
CTL_NODE_NAMED,
CTL_NODE_LEAF,
CTL_NODE_INDEXED,
MAX_CTL_NODE
};
typedef int (*ctl_arg_parser)(const void *arg, void *dest, size_t dest_size);
struct ctl_argument_parser {
size_t dest_offset;
size_t dest_size;
ctl_arg_parser parser;
};
struct ctl_argument {
size_t dest_size;
struct ctl_argument_parser parsers[];
};
#define sizeof_member(t, m) sizeof(((t *)0)->m)
#define CTL_ARG_PARSER(t, p)\
{0, sizeof(t), p}
#define CTL_ARG_PARSER_STRUCT(t, m, p)\
{offsetof(t, m), sizeof_member(t, m), p}
#define CTL_ARG_PARSER_END {0, 0, NULL}
struct ctl_node {
const char *name;
enum ctl_node_type type;
node_callback cb[MAX_CTL_QUERY_TYPE];
struct ctl_argument *arg;
struct ctl_node *children;
};
struct ctl *ctl_new(void);
void ctl_delete(struct ctl *stats);
int ctl_load_config_from_string(PMEMobjpool *pop, const char *cfg_string);
int ctl_load_config_from_file(PMEMobjpool *pop, const char *cfg_file);
void ctl_register_module_node(struct ctl *c,
const char *name, struct ctl_node *n);
int ctl_arg_boolean(const void *arg, void *dest, size_t dest_size);
#define CTL_ARG_BOOLEAN {sizeof(int),\
{{0, sizeof(int), ctl_arg_boolean},\
CTL_ARG_PARSER_END}};
int ctl_arg_integer(const void *arg, void *dest, size_t dest_size);
#define CTL_ARG_INT {sizeof(int),\
{{0, sizeof(int), ctl_arg_integer},\
CTL_ARG_PARSER_END}};
#define CTL_ARG_LONG_LONG {sizeof(long long),\
{{0, sizeof(long long), ctl_arg_integer},\
CTL_ARG_PARSER_END}};
int ctl_arg_string(const void *arg, void *dest, size_t dest_size);
#define CTL_ARG_STRING(len) {len,\
{{0, len, ctl_arg_string},\
CTL_ARG_PARSER_END}};
#define CTL_STR(name) #name
#define CTL_NODE_END {NULL, CTL_NODE_UNKNOWN, {NULL, NULL, NULL}, NULL, NULL}
#define CTL_NODE(name)\
ctl_node_##name
#define CTL_CHILD(name)\
{CTL_STR(name), CTL_NODE_NAMED, {NULL, NULL, NULL}, NULL,\
(struct ctl_node *)CTL_NODE(name)}
#define CTL_INDEXED(name)\
{CTL_STR(name), CTL_NODE_INDEXED, {NULL, NULL, NULL}, NULL,\
(struct ctl_node *)CTL_NODE(name)}
#define CTL_READ_HANDLER(name)\
ctl_##name##_read
#define CTL_WRITE_HANDLER(name)\
ctl_##name##_write
#define CTL_RUNNABLE_HANDLER(name)\
ctl_##name##_runnable
#define CTL_ARG(name)\
ctl_arg_##name
#define CTL_LEAF_RO(name)\
{CTL_STR(name), CTL_NODE_LEAF, {CTL_READ_HANDLER(name), NULL, NULL}, NULL, NULL}
#define CTL_LEAF_WO(name)\
{CTL_STR(name), CTL_NODE_LEAF, {NULL, CTL_WRITE_HANDLER(name), NULL},\
&CTL_ARG(name), NULL}
#define CTL_LEAF_RUNNABLE(name)\
{CTL_STR(name), CTL_NODE_LEAF, {NULL, NULL, CTL_RUNNABLE_HANDLER(name)},\
NULL, NULL}
#define CTL_LEAF_RW(name)\
{CTL_STR(name), CTL_NODE_LEAF,\
{CTL_READ_HANDLER(name), CTL_WRITE_HANDLER(name), NULL},\
&CTL_ARG(name), NULL}
#define CTL_REGISTER_MODULE(_ctl, name)\
ctl_register_module_node((_ctl), CTL_STR(name),\
(struct ctl_node *)CTL_NODE(name))
#endif