From 7d0cfad38c107708d12004695d9db97d44b233d8 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 11 May 2023 11:40:18 -0500 Subject: [PATCH] Add decomposition support to dump_cfg --- ldms/python/ldmsd/ldmsd_communicator.py | 12 ++-- ldms/python/ldmsd/ldmsd_controller | 4 +- ldms/src/ldmsd/ldmsctl.c | 11 +++ ldms/src/ldmsd/ldmsd.h | 5 +- ldms/src/ldmsd/ldmsd_config.c | 12 +--- ldms/src/ldmsd/ldmsd_prdcr.c | 4 +- ldms/src/ldmsd/ldmsd_request.c | 94 +++++++++++++++---------- ldms/src/ldmsd/ldmsd_request_util.c | 2 + 8 files changed, 86 insertions(+), 58 deletions(-) diff --git a/ldms/python/ldmsd/ldmsd_communicator.py b/ldms/python/ldmsd/ldmsd_communicator.py index 3e7fcaaf8..769d511bf 100644 --- a/ldms/python/ldmsd/ldmsd_communicator.py +++ b/ldms/python/ldmsd/ldmsd_communicator.py @@ -144,7 +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']}, + 'dump_cfg': {'req_attr':['path'], 'opt_attr': []}, 'set_info': {'req_attr': ['instance'], 'opt_attr': []}, 'xprt_stats': {'req_attr':[], 'opt_attr': ['reset']}, 'thread_stats': {'req_attr':[], 'opt_attr': ['reset']}, @@ -1043,17 +1043,15 @@ 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 + path - The path to write the configuration file 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' + if path is None or path is True: + return errno.EINVAL, "Please specify valid configuration path argument" req = LDMSD_Request(command_id=LDMSD_Request.DUMP_CFG, - attrs = [ LDMSD_Req_Attr(attr_id=LDMSD_Req_Attr.STRING, value=filename) ] + attrs = [ LDMSD_Req_Attr(attr_id=LDMSD_Req_Attr.PATH, value=path) ] ) try: req.send(self) diff --git a/ldms/python/ldmsd/ldmsd_controller b/ldms/python/ldmsd/ldmsd_controller index d3e3d7ffe..1e7be0e69 100755 --- a/ldms/python/ldmsd/ldmsd_controller +++ b/ldms/python/ldmsd/ldmsd_controller @@ -260,7 +260,9 @@ class LdmsdCmdParser(cmd.Cmd): Dump the current running configuration to a file specified in the path Parameters: - path - path to file + path - path to valid directory to write LDMSD configuration file. + Filename is generated using the hostname and port of the ldmsd + that received the configuration request. e.g. -.conf """ arg = self.handle_args('dump_cfg', arg) if arg: diff --git a/ldms/src/ldmsd/ldmsctl.c b/ldms/src/ldmsd/ldmsctl.c index 79d384af8..52c00aa6e 100644 --- a/ldms/src/ldmsd/ldmsctl.c +++ b/ldms/src/ldmsd/ldmsctl.c @@ -429,6 +429,15 @@ static void help_loglevel() " e.g., xprt.* to change the transport-related log levels.\n"); } +static void help_dump_cfg() +{ + printf( "\nDump the ldmsd's currently running configuration to path\n\n" + "Parameters:\n" + " path= Path to directory where ldmsd should write the running configuration.\n" + " LDMSD will write to file matching LDMSD's - used in\n" + " configuration request.\n"); +} + static void help_metric_sets_default_authz() { printf( "\nSet the default authorization values for subsequently created metric sets\n\n" @@ -2476,6 +2485,7 @@ static struct command command_tbl[] = { { "config", LDMSD_PLUGN_CONFIG_REQ, NULL, help_config, resp_generic }, { "daemon_exit", LDMSD_EXIT_DAEMON_REQ, NULL, help_daemon_exit, resp_daemon_exit }, { "daemon_status", LDMSD_DAEMON_STATUS_REQ, NULL, help_daemon_status, resp_daemon_status }, + { "dump_cfg", LDMSD_DUMP_CFG_REQ, NULL, help_dump_cfg, resp_generic }, { "failover_config", LDMSD_FAILOVER_CONFIG_REQ, NULL, help_failover_config, resp_generic }, { "failover_peercfg_start", LDMSD_FAILOVER_PEERCFG_START_REQ, NULL, @@ -2490,6 +2500,7 @@ static struct command command_tbl[] = { help_failover_stop, resp_generic }, { "greeting", LDMSD_GREETING_REQ, NULL, help_greeting, resp_greeting }, { "help", LDMSCTL_HELP, handle_help, NULL, NULL }, + { "help", LDMSCTL_HELP, handle_help, NULL, NULL }, { "listen", LDMSD_LISTEN_REQ, NULL, help_listen, resp_generic }, { "load", LDMSD_PLUGN_LOAD_REQ, NULL, help_load, resp_generic }, { "log_status", LDMSD_LOG_STATUS_REQ, NULL, help_log_status, resp_log_status }, diff --git a/ldms/src/ldmsd/ldmsd.h b/ldms/src/ldmsd/ldmsd.h index cfc0749f7..6422da42d 100644 --- a/ldms/src/ldmsd/ldmsd.h +++ b/ldms/src/ldmsd/ldmsd.h @@ -209,8 +209,8 @@ 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 */ + char *conn_auth_dom_name; /* auth domain name */ + char *conn_auth; /* auth plugin for the connection */ struct attr_value_list *conn_auth_args; /* auth options of the connection auth */ enum ldmsd_prdcr_state { @@ -745,6 +745,7 @@ struct attr_value_list; struct ldmsd_plugin { char name[LDMSD_MAX_PLUGIN_NAME_LEN]; struct attr_value_list *av_list; + struct attr_value_list *kw_list; enum ldmsd_plugin_type { LDMSD_PLUGIN_OTHER = 0, LDMSD_PLUGIN_SAMPLER, diff --git a/ldms/src/ldmsd/ldmsd_config.c b/ldms/src/ldmsd/ldmsd_config.c index de4ad4e85..5510a9164 100644 --- a/ldms/src/ldmsd/ldmsd_config.c +++ b/ldms/src/ldmsd/ldmsd_config.c @@ -207,6 +207,7 @@ void destroy_plugin(struct ldmsd_plugin_cfg *p) free(p->libpath); free(p->name); av_free(p->plugin->av_list); + av_free(p->plugin->kw_list); LIST_REMOVE(p, entry); dlclose(p->handle); free(p); @@ -316,16 +317,7 @@ 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); - } - */ + pi->plugin->kw_list = av_copy(_kw_list); pthread_mutex_unlock(&pi->lock); return rc; } diff --git a/ldms/src/ldmsd/ldmsd_prdcr.c b/ldms/src/ldmsd/ldmsd_prdcr.c index 7f2424f82..bd43ea991 100644 --- a/ldms/src/ldmsd/ldmsd_prdcr.c +++ b/ldms/src/ldmsd/ldmsd_prdcr.c @@ -836,8 +836,8 @@ 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) + prdcr->conn_auth_dom_name = strdup(auth_dom->obj.name); + if (!prdcr->conn_auth_dom_name) goto out; prdcr->conn_auth = strdup(auth_dom->plugin); if (!prdcr->conn_auth) diff --git a/ldms/src/ldmsd/ldmsd_request.c b/ldms/src/ldmsd/ldmsd_request.c index 604948829..c9b2fe469 100644 --- a/ldms/src/ldmsd/ldmsd_request.c +++ b/ldms/src/ldmsd/ldmsd_request.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -6148,15 +6149,33 @@ static int greeting_handler(ldmsd_req_ctxt_t reqc) static int dump_cfg_handler(ldmsd_req_ctxt_t reqc) { - FILE *fp; + FILE *fp = NULL; char *filename = NULL; extern struct plugin_list plugin_list; struct ldmsd_plugin_cfg *p; int rc; int i; + char hostname[128], port_no[32]; + rc = ldms_xprt_names(reqc->xprt->ldms.ldms, hostname, sizeof(hostname), port_no, sizeof(port_no), + NULL, 0, NULL, 0, NI_NAMEREQD | NI_NUMERICSERV); reqc->errcode = 0; - filename = ldmsd_req_attr_str_value_get_by_id(reqc, LDMSD_ATTR_STRING); - fp = fopen(filename, "w+"); + filename = ldmsd_req_attr_str_value_get_by_id(reqc, LDMSD_ATTR_PATH); + if (!filename || strlen(filename) == 0) { + Snprintf(&reqc->line_buf, &reqc->line_len, + "Invalid path argument. Please specify valid directory path"); + goto err0; + } + char fullpath[sizeof(filename)+sizeof(hostname)+sizeof(port_no)]; + snprintf(fullpath, sizeof(fullpath), "%s/%s-%s.conf", filename, hostname, port_no); + fp = fopen(fullpath, "w+"); + if (!fp) { + Snprintf(&reqc->line_buf, &reqc->line_len, + "Unable to write configuration file at path %s.", fullpath); + goto err0; + } + fprintf(fp, "# This configuration file assumes ldmsd will be started with\n" + "# no command line arguments.\n" + "# e.g. ldmsd -c %s\n\n", fullpath); /* Auth */ ldmsd_auth_t auth; @@ -6175,6 +6194,7 @@ static int dump_cfg_handler(ldmsd_req_ctxt_t reqc) ldmsd_cfg_unlock(LDMSD_CFGOBJ_AUTH); /* Listeners */ ldmsd_listen_t listen; + ldmsd_cfg_lock(LDMSD_CFGOBJ_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", @@ -6190,6 +6210,7 @@ static int dump_cfg_handler(ldmsd_req_ctxt_t reqc) } fprintf(fp, "\n"); } + ldmsd_cfg_unlock(LDMSD_CFGOBJ_LISTEN); /* Producers */ ldmsd_prdcr_t prdcr = NULL; @@ -6204,13 +6225,13 @@ static int dump_cfg_handler(ldmsd_req_ctxt_t reqc) prdcr->port_no, prdcr->xprt_name, ldmsd_prdcr_type2str(prdcr->type), prdcr->conn_intrvl_us, - prdcr->conn_auth_name, + prdcr->conn_auth_dom_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); + fprintf(fp, "prdcr_subscribe regex=^%s$ stream=%s\n", prdcr->obj.name, s->name); } ldmsd_prdcr_unlock(prdcr); } @@ -6225,6 +6246,12 @@ static int dump_cfg_handler(ldmsd_req_ctxt_t reqc) fprintf(fp, " "); fprintf(fp, "%s=%s", v->name, v->value); } + for (i = 0; i < p->plugin->kw_list->count; i++) { + struct attr_value *k = &p->plugin->kw_list->list[i]; + if (i > 0) + fprintf(fp, " "); + fprintf(fp, "%s", k->name); + } fprintf(fp, "\n"); if (p->plugin->type == LDMSD_PLUGIN_SAMPLER) fprintf(fp, "start name=%s interval=%ld offset=%ld\n", @@ -6232,7 +6259,7 @@ static int dump_cfg_handler(ldmsd_req_ctxt_t reqc) p->sample_interval_us, p->sample_offset_us); } - /* Updaters WIP - push modes */ + /* Updaters */ ldmsd_name_match_t match; ldmsd_updtr_t updtr; char *sel_str; @@ -6241,6 +6268,7 @@ static int dump_cfg_handler(ldmsd_req_ctxt_t reqc) ldmsd_cfg_lock(LDMSD_CFGOBJ_UPDTR); for (updtr = ldmsd_updtr_first(); updtr; updtr = ldmsd_updtr_next(updtr)) { + ldmsd_updtr_lock(updtr); /* Initial updater configuration */ fprintf(fp, "updtr_add name=%s", updtr->obj.name); if (updtr->is_auto_task) @@ -6251,43 +6279,34 @@ static int dump_cfg_handler(ldmsd_req_ctxt_t reqc) updtr_mode = "push=onchange"; if (updtr_mode) fprintf(fp, " %s", updtr_mode); - fprintf(fp, " interval=%ld\n", updtr->default_task.task.sched_us); + fprintf(fp, " interval=%ld", updtr->default_task.task.sched_us); + if (updtr->default_task.task_flags & LDMSD_TASK_F_SYNCHRONOUS) + fprintf(fp, " offset=%ld\n", updtr->default_task.task.offset_us); + else + fprintf(fp, "\n"); /* 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); + 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); - } + 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); } } - fprintf(fp, "updtr_start name=%s\n", updtr->obj.name); + /* Check updater status */ + if (updtr->state == LDMSD_UPDTR_STATE_RUNNING) + fprintf(fp, "updtr_start name=%s\n", updtr->obj.name); + ldmsd_updtr_unlock(updtr); } ldmsd_cfg_unlock(LDMSD_CFGOBJ_UPDTR); /* Storage Policies */ @@ -6301,25 +6320,28 @@ static int dump_cfg_handler(ldmsd_req_ctxt_t reqc) "container=%s " "schema=%s " "flush=%ld " - "perm=%d ", + "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, " decomposition=%s", strgp->decomp_name); 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; +err0: + rc = EINVAL; + reqc->errcode = EINVAL; + goto send_reply; send_reply: - fclose(fp); + if (fp) + fclose(fp); free(filename); ldmsd_send_req_response(reqc, reqc->line_buf); return rc; diff --git a/ldms/src/ldmsd/ldmsd_request_util.c b/ldms/src/ldmsd/ldmsd_request_util.c index fc5832988..8f629395f 100644 --- a/ldms/src/ldmsd/ldmsd_request_util.c +++ b/ldms/src/ldmsd/ldmsd_request_util.c @@ -69,6 +69,7 @@ const struct req_str_id req_str_id_table[] = { { "daemon", LDMSD_DAEMON_STATUS_REQ }, { "daemon_exit", LDMSD_EXIT_DAEMON_REQ }, { "daemon_status", LDMSD_DAEMON_STATUS_REQ }, + { "dump_cfg", LDMSD_DUMP_CFG_REQ }, { "env", LDMSD_ENV_REQ }, { "exit", LDMSD_EXIT_DAEMON_REQ }, { "failover_config", LDMSD_FAILOVER_CONFIG_REQ }, @@ -219,6 +220,7 @@ const char *ldmsd_req_id2str(enum ldmsd_request req_id) switch (req_id) { case LDMSD_EXAMPLE_REQ : return "EXAMPLE_REQ"; case LDMSD_GREETING_REQ : return "GREETING_REQ"; + case LDMSD_DUMP_CFG_REQ : return "DUMP_CFG_REQ"; case LDMSD_PRDCR_ADD_REQ : return "PRDCR_ADD_REQ"; case LDMSD_PRDCR_DEL_REQ : return "PRDCR_DEL_REQ";