Skip to content

Commit

Permalink
Command to dump the current running configuration
Browse files Browse the repository at this point in the history
Command dump_cfg added to ldmsd_controller and ldmsd_communicator.
Writes the current running configuration to a file named after the daemon's host
and communication port, <hostname>-<port>.conf, in path specified in argument. If
no path is specified it writes the file to the user's home path.

Parameters:
path - [optional] The path to the configuration file
  • Loading branch information
nick-enoent authored and tom95858 committed Jul 3, 2023
1 parent 2da9785 commit c40b505
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 1 deletion.
32 changes: 31 additions & 1 deletion ldms/python/ldmsd/ldmsd_communicator.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
##### Misc. #####
'greeting': {'req_attr': [], 'opt_attr': ['name', 'offset', 'level', 'test', 'path']},
'example': {'req_attr': [], 'opt_attr': []},
'dump_cfg': {'req_attr':[], 'opt_attr': ['path']},
'set_info': {'req_attr': ['instance'], 'opt_attr': []},
'xprt_stats': {'req_attr':[], 'opt_attr': ['reset']},
'thread_stats': {'req_attr':[], 'opt_attr': ['reset']},
Expand Down Expand Up @@ -456,6 +457,7 @@ class LDMSD_Request(object):
EXAMPLE = 1
GREETING = 2
CFG_CNTR = 3
DUMP_CFG = 4

PRDCR_ADD = 0x100
PRDCR_DEL = 0x100 + 1
Expand Down Expand Up @@ -560,6 +562,7 @@ class LDMSD_Request(object):
'example': {'id': EXAMPLE},
'greeting': {'id': GREETING},
'cfg_cntr': {'id': CFG_CNTR},
'dump_cfg': {'id': DUMP_CFG},

'prdcr_add': {'id': PRDCR_ADD},
'prdcr_del': {'id': PRDCR_DEL},
Expand Down Expand Up @@ -949,7 +952,9 @@ def reconnect(self, timeout=0):

def connect(self, timeout=0):
try:
self.ldms.connect(self.host, self.port, timeout=timeout)
if not self.ldms:
self.ldms = ldms.Xprt(name=self.xprt, auth=self.auth, auth_opts=self.auth_opt)
rc = self.ldms.connect(self.host, self.port, timeout=timeout)
except Exception as e:
if self.auth is not None:
if self.auth_opt is not None:
Expand All @@ -962,6 +967,8 @@ def connect(self, timeout=0):
print(f'{e}: connecting to {self.host} on port {self.port} using {self.xprt}{auth_s}')
self.state = self.CLOSED
return errno.ENOTCONN
if rc:
return 1
self.type = 'inband'
self.state = self.CONNECTED
rc, self.CFG_CNTR = self.getCfgCntr()
Expand Down Expand Up @@ -1032,6 +1039,29 @@ def greeting(self, name=None, offset=None, level=None, test=None, path=None):
except Exception as e:
return errno.ENOTCONN, str(e)

def dump_cfg(self, path=None):
"""
Dumps the currently running configuration of a running ldmsd
Parameters:
path - The path to write the configuration to
defaults to the current users home directory
Returns:
- status is an errno from the errno module
- data is an error message if status is !=0 or None
"""
if path is None:
path = os.path.expanduser('~')
filename = f'{path}/{self.host}-{self.port}.conf'
req = LDMSD_Request(command_id=LDMSD_Request.DUMP_CFG,
attrs = [ LDMSD_Req_Attr(attr_id=LDMSD_Req_Attr.STRING, value=filename) ]
)
try:
req.send(self)
resp = req.receive(self)
return resp['errcode'], resp['msg']
except Exception as e:
return errno.ENOTCONN, str(e)

def auth_add(self, name, plugin=None, auth_opt=None):
"""
Add an authentication domain
Expand Down
13 changes: 13 additions & 0 deletions ldms/python/ldmsd/ldmsd_controller
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,19 @@ class LdmsdCmdParser(cmd.Cmd):
for cmd in fin:
self.onecmd(cmd)

def do_dump_cfg(self, arg):
"""
Dump the current running configuration to a file specified in the path
Parameters:
path - path to file
"""
arg = self.handle_args('dump_cfg', arg)
if arg:
rc, msg = self.comm.dump_cfg(arg['path'])
if rc:
print(f'Error {rc} printing current configuration: {msg}')

def do_source(self, arg):
"""
Parse commands from the specified file as if they were entered
Expand Down
5 changes: 5 additions & 0 deletions ldms/src/ldmsd/ldmsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,11 @@ ldmsd_listen_t ldmsd_listen_new(char *xprt, char *port, char *host, char *auth)
errno = ENOMEM;
goto err;
}
listen->auth_dom_name = strdup(auth_dom->obj.name);
if (!listen->auth_dom_name) {
errno = ENOMEM;
goto err;
}
if (auth_dom->attrs) {
listen->auth_attrs = av_copy(auth_dom->attrs);
if (!listen->auth_attrs) {
Expand Down
3 changes: 3 additions & 0 deletions ldms/src/ldmsd/ldmsd.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ typedef struct ldmsd_prdcr {
char *xprt_name; /* Transport name */
ldms_t xprt;
long conn_intrvl_us; /* connect interval */
char *conn_auth_name; /* auth domain name */
char *conn_auth; /* auth method for the connection */
struct attr_value_list *conn_auth_args; /* auth options of the connection auth */

Expand Down Expand Up @@ -743,6 +744,7 @@ int process_config_file(const char *path, int *lineno, int trust);
struct attr_value_list;
struct ldmsd_plugin {
char name[LDMSD_MAX_PLUGIN_NAME_LEN];
struct attr_value_list *av_list;
enum ldmsd_plugin_type {
LDMSD_PLUGIN_OTHER = 0,
LDMSD_PLUGIN_SAMPLER,
Expand Down Expand Up @@ -1370,6 +1372,7 @@ typedef struct ldmsd_listen {
unsigned short port_no;
char *host;
char *auth_name;
char *auth_dom_name;
struct attr_value_list *auth_attrs;
ldms_t x;
} *ldmsd_listen_t;
Expand Down
12 changes: 12 additions & 0 deletions ldms/src/ldmsd/ldmsd_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ void destroy_plugin(struct ldmsd_plugin_cfg *p)
{
free(p->libpath);
free(p->name);
av_free(p->plugin->av_list);
LIST_REMOVE(p, entry);
dlclose(p->handle);
free(p);
Expand Down Expand Up @@ -314,6 +315,17 @@ int ldmsd_config_plugin(char *plugin_name,

pthread_mutex_lock(&pi->lock);
rc = pi->plugin->config(pi->plugin, _kw_list, _av_list);
pi->plugin->av_list = av_copy(_av_list);
/*
int i;
pi->plugin->av_list = av_new(_av_list->count);
pi->plugin->av_list->count = _av_list->count;
for (i = 0; i < _av_list->count; i++) {
struct attr_value *v = &_av_list->list[i];
pi->plugin->av_list->list[i].name = strdup(v->name);
pi->plugin->av_list->list[i].value = strdup(v->value);
}
*/
pthread_mutex_unlock(&pi->lock);
return rc;
}
Expand Down
3 changes: 3 additions & 0 deletions ldms/src/ldmsd/ldmsd_prdcr.c
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,9 @@ ldmsd_prdcr_new_with_auth(const char *name, const char *xprt_name,
errno = ENOENT;
goto out;
}
prdcr->conn_auth_name = strdup(auth_dom->obj.name);
if (!prdcr->conn_auth_name)
goto out;
prdcr->conn_auth = strdup(auth_dom->plugin);
if (!prdcr->conn_auth)
goto out;
Expand Down
181 changes: 181 additions & 0 deletions ldms/src/ldmsd/ldmsd_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ struct request_handler_entry {

static int example_handler(ldmsd_req_ctxt_t req_ctxt);
static int ldmsd_cfg_cntr_handler(ldmsd_req_ctxt_t req_ctxt);
static int dump_cfg_handler(ldmsd_req_ctxt_t req_ctxt);
static int prdcr_add_handler(ldmsd_req_ctxt_t req_ctxt);
static int prdcr_del_handler(ldmsd_req_ctxt_t req_ctxt);
static int prdcr_start_handler(ldmsd_req_ctxt_t req_ctxt);
Expand Down Expand Up @@ -311,6 +312,7 @@ static int cmd_line_arg_set_handler(ldmsd_req_ctxt_t reqc);
static struct request_handler_entry request_handler[] = {
[LDMSD_EXAMPLE_REQ] = { LDMSD_EXAMPLE_REQ, example_handler, XALL },
[LDMSD_CFG_CNTR_REQ] = { LDMSD_CFG_CNTR_REQ, ldmsd_cfg_cntr_handler, XUG },
[LDMSD_DUMP_CFG_REQ] = { LDMSD_DUMP_CFG_REQ, dump_cfg_handler, XUG },

/* PRDCR */
[LDMSD_PRDCR_ADD_REQ] = {
Expand Down Expand Up @@ -6144,6 +6146,185 @@ static int greeting_handler(ldmsd_req_ctxt_t reqc)
return 0;
}

static int dump_cfg_handler(ldmsd_req_ctxt_t reqc)
{
FILE *fp;
char *filename = NULL;
extern struct plugin_list plugin_list;
struct ldmsd_plugin_cfg *p;
int rc;
int i;
reqc->errcode = 0;
filename = ldmsd_req_attr_str_value_get_by_id(reqc, LDMSD_ATTR_STRING);
fp = fopen(filename, "w+");

/* Auth */
ldmsd_auth_t auth;
ldmsd_cfg_lock(LDMSD_CFGOBJ_AUTH);
for (auth = (ldmsd_auth_t)ldmsd_cfgobj_first(LDMSD_CFGOBJ_AUTH); auth;
auth = (ldmsd_auth_t)ldmsd_cfgobj_next(&auth->obj)) {
fprintf(fp, "auth_add name=%s plugin=%s", auth->obj.name, auth->plugin);
if (auth->attrs) {
for (i = 0; i < auth->attrs->count; i++) {
struct attr_value *v = &auth->attrs->list[i];
fprintf(fp, " %s=%s", v->name, v->value);
}
}
fprintf(fp, "\n");
}
ldmsd_cfg_unlock(LDMSD_CFGOBJ_AUTH);
/* Listeners */
ldmsd_listen_t listen;
for (listen = (ldmsd_listen_t)ldmsd_cfgobj_first(LDMSD_CFGOBJ_LISTEN); listen;
listen = (ldmsd_listen_t)ldmsd_cfgobj_next(&listen->obj)) {
fprintf(fp, "listen xprt=%s port=%d",
listen->xprt,
listen->port_no);
if (listen->host)
fprintf(fp, " host=%s", listen->host);
if (listen->auth_name) {
if (listen->auth_dom_name)
fprintf(fp, " auth=%s", listen->auth_dom_name);
else
fprintf(fp, " auth=DEFAULT");
}
fprintf(fp, "\n");
}
/* Producers */
ldmsd_prdcr_t prdcr = NULL;

ldmsd_cfg_lock(LDMSD_CFGOBJ_PRDCR);
for (prdcr = ldmsd_prdcr_first(); prdcr;
prdcr = ldmsd_prdcr_next(prdcr)) {
ldmsd_prdcr_stream_t s;

ldmsd_prdcr_lock(prdcr);
fprintf(fp, "prdcr_add name=%s host=%s port=%d xprt=%s type=%s interval=%ld auth=%s uid=%d gid=%d\n",
prdcr->obj.name, prdcr->host_name,
prdcr->port_no, prdcr->xprt_name,
ldmsd_prdcr_type2str(prdcr->type),
prdcr->conn_intrvl_us,
prdcr->conn_auth_name,
prdcr->obj.uid, prdcr->obj.gid);
if (prdcr->conn_state == LDMSD_PRDCR_STATE_CONNECTED)
fprintf(fp, "prdcr_start name=%s\n", prdcr->obj.name);
/* Streams */
LIST_FOREACH(s, &prdcr->stream_list, entry) {
fprintf(fp, "prdcr_subscribe regex=%s stream=%s\n", prdcr->obj.name, s->name);
}
ldmsd_prdcr_unlock(prdcr);
}
ldmsd_cfg_unlock(LDMSD_CFGOBJ_PRDCR);
/* Plugins */
LIST_FOREACH(p, &plugin_list, entry) {
fprintf(fp, "load name=%s\n", p->name);
fprintf(fp, "config name=%s ", p->name);
for (i = 0; i < p->plugin->av_list->count; i++) {
struct attr_value *v = &p->plugin->av_list->list[i];
if (i > 0)
fprintf(fp, " ");
fprintf(fp, "%s=%s", v->name, v->value);
}
fprintf(fp, "\n");
if (p->plugin->type == LDMSD_PLUGIN_SAMPLER)
fprintf(fp, "start name=%s interval=%ld offset=%ld\n",
p->plugin->name,
p->sample_interval_us,
p->sample_offset_us);
}
/* Updaters WIP - push modes */
ldmsd_name_match_t match;
ldmsd_updtr_t updtr;
char *sel_str;
char *updtr_mode = NULL;

ldmsd_cfg_lock(LDMSD_CFGOBJ_UPDTR);
for (updtr = ldmsd_updtr_first(); updtr;
updtr = ldmsd_updtr_next(updtr)) {
/* Initial updater configuration */
fprintf(fp, "updtr_add name=%s", updtr->obj.name);
if (updtr->is_auto_task)
updtr_mode = "auto_interval=true";
else if (updtr->push_flags & LDMSD_UPDTR_F_PUSH)
updtr_mode = "push=true";
else if (updtr->push_flags & LDMSD_UPDTR_F_PUSH_CHANGE)
updtr_mode = "push=onchange";
if (updtr_mode)
fprintf(fp, " %s", updtr_mode);
fprintf(fp, " interval=%ld\n", updtr->default_task.task.sched_us);
/* Add producers to updater */
ldmsd_prdcr_ref_t ref;
for (ref = ldmsd_updtr_prdcr_first(updtr); ref;
ref = ldmsd_updtr_prdcr_next(ref)) {
ldmsd_prdcr_lock(ref->prdcr);
if (ref->prdcr->conn_state == LDMSD_PRDCR_STATE_CONNECTED)
fprintf(fp, "updtr_prdcr_add name=%s regex=%s\n", updtr->obj.name, ref->prdcr->obj.name);
ldmsd_prdcr_unlock(ref->prdcr);
}
/* Add match sets if there are any */
if (!LIST_EMPTY(&updtr->match_list)) {
LIST_FOREACH(match, &updtr->match_list, entry) {
for (ref = ldmsd_updtr_prdcr_first(updtr); ref;
ref = ldmsd_updtr_prdcr_next(ref)) {
ldmsd_prdcr_lock(ref->prdcr);
ldmsd_prdcr_set_t prd_set;
for (prd_set = ldmsd_prdcr_set_first(ref->prdcr); prd_set;
prd_set = ldmsd_prdcr_set_next(prd_set)) {
if (match->selector == LDMSD_NAME_MATCH_INST_NAME)
rc = regexec(&match->regex, prd_set->inst_name, 0, NULL, 0);
else
rc = regexec(&match->regex, prd_set->schema_name, 0, NULL, 0);
if (rc)
continue;
if (match->selector == LDMSD_NAME_MATCH_INST_NAME)
sel_str = "inst";
else
sel_str = "schema";
fprintf(fp, "updtr_match_add name=%s match=%s regex=%s\n",
updtr->obj.name, sel_str, match->regex_str);
}
ldmsd_prdcr_unlock(ref->prdcr);
}
}
}
fprintf(fp, "updtr_start name=%s\n", updtr->obj.name);
}
ldmsd_cfg_unlock(LDMSD_CFGOBJ_UPDTR);
/* Storage Policies */
ldmsd_strgp_t strgp;

ldmsd_cfg_lock(LDMSD_CFGOBJ_STRGP);
for (strgp = ldmsd_strgp_first(); strgp;
strgp = ldmsd_strgp_next(strgp)) {
fprintf(fp, "strgp_add name=%s "
"plugin=%s "
"container=%s "
"schema=%s "
"flush=%ld "
"perm=%d ",
strgp->obj.name,
strgp->plugin_name,
strgp->container,
strgp->schema,
strgp->flush_interval.tv_sec,
strgp->obj.perm);
/*
if (strgp->decomp)
fprintf(fp, "decomposition=%s", strgp->decomp);
*/
fprintf(fp, "\n");
if (strgp->state == LDMSD_STRGP_STATE_RUNNING)
fprintf(fp, "strgp_start name=%s\n", strgp->obj.name);
}
ldmsd_cfg_unlock(LDMSD_CFGOBJ_STRGP);
goto send_reply;
send_reply:
fclose(fp);
free(filename);
ldmsd_send_req_response(reqc, reqc->line_buf);
return rc;
}

static int unimplemented_handler(ldmsd_req_ctxt_t reqc)
{
size_t cnt;
Expand Down
1 change: 1 addition & 0 deletions ldms/src/ldmsd/ldmsd_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ enum ldmsd_request {
LDMSD_EXAMPLE_REQ = 0x1,
LDMSD_GREETING_REQ = 0x2,
LDMSD_CFG_CNTR_REQ = 0x3,
LDMSD_DUMP_CFG_REQ = 0x4,
LDMSD_PRDCR_ADD_REQ = 0x100,
LDMSD_PRDCR_DEL_REQ,
LDMSD_PRDCR_START_REQ,
Expand Down

0 comments on commit c40b505

Please sign in to comment.