From: Jonathan Rajotte Date: Thu, 8 Sep 2016 22:02:51 +0000 (-0400) Subject: lttng-ctl: add override helper to load api X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=96607445f251caf6774eddea0b874c84fb442044;p=lttng-tools.git lttng-ctl: add override helper to load api User can provide an url override that will be used during the loading of a configuration file. The url format is the same found at lttng-create(1). This correspond to a --set-url operation on lttng-create. Note: an url might be invalid for a trace configuration. The override will fail during the session load (call to lttng_load_session) and simply cancel the loading. e.g Loading a live session with a file:// url override will fail. --- diff --git a/include/lttng/load-internal.h b/include/lttng/load-internal.h index 78cf86a2d..b644717ce 100644 --- a/include/lttng/load-internal.h +++ b/include/lttng/load-internal.h @@ -24,6 +24,7 @@ #include #include +#include /* * Object used by the load_session API. This is opaque to the public library. @@ -35,6 +36,16 @@ struct lttng_load_session_attr { char input_url[PATH_MAX]; /* Overwrite the session if it exists. */ uint32_t overwrite; + /* The raw override url for getter */ + char *raw_override_url; + /* The raw override path url for getter */ + char *raw_override_path_url; + /* The raw override ctrl url for getter */ + char *raw_override_ctrl_url; + /* The raw override data url for getter */ + char *raw_override_data_url; + /* Override struct */ + struct config_load_session_override_attr override_attr; } LTTNG_PACKED; #endif /* LTTNG_LOAD_INTERNAL_ABI_H */ diff --git a/include/lttng/load.h b/include/lttng/load.h index 6b7d68339..f449af0fd 100644 --- a/include/lttng/load.h +++ b/include/lttng/load.h @@ -63,6 +63,45 @@ const char *lttng_load_session_attr_get_input_url( */ int lttng_load_session_attr_get_overwrite( struct lttng_load_session_attr *attr); +/* + * Return the configuration override path url attribute. This attribute + * indicate an override to be applied during the loading of the configuration. + * Null indicates no override will be applied on configuration load. + * + * Caller is responsible for freeing the return value. + */ +const char *lttng_load_session_attr_get_override_path_url( + struct lttng_load_session_attr *attr); + +/* + * Return the configuration override control url attribute. This attribute + * indicate an override to be applied during the loading of the configuration. + * Null indicates no override will be applied on configuration load. + * + * Caller is responsible for freeing the return value. + */ +const char *lttng_load_session_attr_get_override_ctrl_url( + struct lttng_load_session_attr *attr); + +/* + * Return the configuration override data url attribute. This attribute + * indicate an override to be applied during the loading of the configuration. + * Null indicates no override will be applied on configuration load. + * + * Caller is responsible for freeing the return value. + */ +const char *lttng_load_session_attr_get_override_data_url( + struct lttng_load_session_attr *attr); + +/* + * Return the configuration override url attribute. This attribute + * indicate an override to be applied during the loading of the configuration. + * Null indicates no override will be applied on configuration load. + * + * Caller is responsible for freeing the return value. + */ +const char *lttng_load_session_attr_get_override_url( + struct lttng_load_session_attr *attr); /* * Load session attribute setter family functions. @@ -94,6 +133,58 @@ int lttng_load_session_attr_set_input_url( int lttng_load_session_attr_set_overwrite( struct lttng_load_session_attr *attr, int overwrite); +/* + * The following setter are for overriding sessions attributes during the + * loading of a configuration files. Those attributes prevail upon those + * specified in the loaded configuration file. + * */ + +/* + * Set the path url override attribute. + * + * Supported format: + * file://TRACEPATH + */ +int lttng_load_session_attr_set_override_path_url( + struct lttng_load_session_attr *attr, const char *url); + +/* + * Set the control url override attribute. + * + * Supported format: + * NETPROTO://(HOST | IPADDR)[:PORT][/TRACEPATH] + * + * Where NETPROTO is one of tcp,tcp6 + * + * See lttng-create(1) for more detail. + */ +int lttng_load_session_attr_set_override_ctrl_url( + struct lttng_load_session_attr *attr, const char *url); + +/* + * Set the data url override attribute. + * + * Supported format: + * NETPROTO://(HOST | IPADDR)[:PORT][/TRACEPATH] + * + * Where NETPROTO is one of tcp,tcp6 + * + * See lttng-create(1) for more detail. + */ +int lttng_load_session_attr_set_override_data_url( + struct lttng_load_session_attr *attr, const char *url); + +/* + * Set the url override attribute. + * + * Supported format: + * file://TRACEPATH + * NETPROTO://(HOST | IPADDR)[:CTRLPORT[:DATAPORT]][/TRACEPATH] + * + * See lttng-create(1) for more detail. + */ +int lttng_load_session_attr_set_override_url( + struct lttng_load_session_attr *attr, const char *url); /* * Load session configuration(s). * diff --git a/src/common/config/session-config.h b/src/common/config/session-config.h index c4e4797e5..cb006f18e 100644 --- a/src/common/config/session-config.h +++ b/src/common/config/session-config.h @@ -30,6 +30,12 @@ struct config_entry { const char *value; }; +struct config_load_session_override_attr { + char *path_url; + char *ctrl_url; + char *data_url; +}; + /* Instance of a configuration writer. */ struct config_writer; diff --git a/src/lib/lttng-ctl/load.c b/src/lib/lttng-ctl/load.c index fb28f4eae..26feb6f6d 100644 --- a/src/lib/lttng-ctl/load.c +++ b/src/lib/lttng-ctl/load.c @@ -18,12 +18,15 @@ #define _LGPL_SOURCE #include #include +#include #include #include #include #include #include +#include +#include #include "lttng-ctl-helper.h" @@ -35,6 +38,13 @@ struct lttng_load_session_attr *lttng_load_session_attr_create(void) void lttng_load_session_attr_destroy(struct lttng_load_session_attr *attr) { if (attr) { + free(attr->raw_override_url); + free(attr->raw_override_path_url); + free(attr->raw_override_ctrl_url); + free(attr->raw_override_data_url); + free(attr->override_attr.path_url); + free(attr->override_attr.ctrl_url); + free(attr->override_attr.data_url); free(attr); } } @@ -69,6 +79,56 @@ int lttng_load_session_attr_get_overwrite( return attr ? attr->overwrite : -LTTNG_ERR_INVALID; } +const char *lttng_load_session_attr_get_override_path_url( + struct lttng_load_session_attr *attr) +{ + const char *ret = NULL; + + if (attr && attr->override_attr.path_url) { + ret = attr->raw_override_path_url; + } + + return ret; +} + +const char *lttng_load_session_attr_get_override_ctrl_url( + struct lttng_load_session_attr *attr) +{ + const char *ret = NULL; + + if (attr && attr->override_attr.ctrl_url) { + ret = attr->raw_override_ctrl_url; + } + + return ret; +} + +const char *lttng_load_session_attr_get_override_data_url( + struct lttng_load_session_attr *attr) +{ + const char *ret = NULL; + + if (attr && attr->override_attr.data_url) { + ret = attr->raw_override_data_url; + } + + return ret; +} + +const char *lttng_load_session_attr_get_override_url( + struct lttng_load_session_attr *attr) +{ + const char *ret = NULL; + + if (attr && (attr->override_attr.path_url || + (attr->override_attr.ctrl_url && + attr->override_attr.data_url))) { + ret = attr->raw_override_url; + } + + return ret; +} + int lttng_load_session_attr_set_session_name( struct lttng_load_session_attr *attr, const char *session_name) { @@ -152,6 +212,383 @@ end: return ret; } +int lttng_load_session_attr_set_override_path_url( + struct lttng_load_session_attr *attr, const char *url) +{ + int ret = 0; + ssize_t ret_size; + struct lttng_uri *uri = NULL; + char *url_str = NULL; + char *raw_str = NULL; + int tmp = 0; + + if (!attr) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + if (attr->override_attr.ctrl_url || attr->override_attr.data_url) { + /* + * FIXME: return a more meaningful error. + * Setting a path override after a ctrl or data override make no + * sense and show that the user do not know what he is doing. + * */ + ret = -LTTNG_ERR_INVALID; + goto end; + } + + /* + * FIXME: uri_parse should be able to take as parameter the protocol + * type to check validity with or the exclusion. For now only check on + * the parsing validity it will fail later on. + * */ + ret_size = uri_parse(url, &uri); + if (ret_size != 1) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + /* Populate the internal override representation */ + url_str = zmalloc(PATH_MAX); + if (!url_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + tmp = uri_to_str_url(&uri[0], url_str, PATH_MAX); + if (tmp < 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + raw_str = strndup(url, PATH_MAX); + if (!raw_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + /* Squash old value if any */ + free(attr->override_attr.path_url); + free(attr->raw_override_path_url); + + /* Populate the object */ + attr->override_attr.path_url = url_str; + attr->raw_override_path_url = raw_str; + + url_str = NULL; + raw_str = NULL; +end: + free(raw_str); + free(url_str); + free(uri); + return ret; +} + +int lttng_load_session_attr_set_override_ctrl_url( + struct lttng_load_session_attr *attr, const char *url) +{ + int ret = 0; + ssize_t ret_size; + struct lttng_uri *uri = NULL; + char *url_str = NULL; + char *raw_str = NULL; + int tmp = 0; + + if (!attr) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + if (attr->override_attr.path_url) { + /* + * FIXME: return a more meaningful error. + * Setting a ctrl override after a path override make no + * sense and show that the user do not know what he is doing. + * */ + ret = -LTTNG_ERR_INVALID; + goto end; + } + + /* + * FIXME: uri_parse should be able to take as parameter the protocol + * type to check validity with or the exclusion. For now only check on + * the parsing validity it will fail later on. + * */ + ret_size = uri_parse(url, &uri); + if (ret_size < 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + if (uri[0].port == 0) { + uri[0].port = DEFAULT_NETWORK_CONTROL_PORT; + } + + url_str = zmalloc(PATH_MAX); + if (!url_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + tmp = uri_to_str_url(&uri[0], url_str, PATH_MAX); + if (tmp < 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + raw_str = strndup(url, PATH_MAX); + if (!raw_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + /* Squash old value if any */ + free(attr->override_attr.ctrl_url); + free(attr->raw_override_ctrl_url); + + /* Populate the object */ + attr->override_attr.ctrl_url = url_str; + attr->raw_override_ctrl_url = raw_str; + + url_str = NULL; + raw_str = NULL; + +end: + free(raw_str); + free(url_str); + free(uri); + return ret; +} + +int lttng_load_session_attr_set_override_data_url( + struct lttng_load_session_attr *attr, const char *url) +{ + int ret = 0; + ssize_t ret_size; + struct lttng_uri *uri = NULL; + char *url_str = NULL; + char *raw_str = NULL; + int tmp = 0; + + if (!attr) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + if (attr->override_attr.path_url) { + /* + * FIXME: return a more meaningful error. + * Setting a data override after a path override make no + * sense and show that the user do not know what he is doing. + * */ + ret = -LTTNG_ERR_INVALID; + goto end; + } + + /* + * FIXME: uri_parse should be able to take as parameter the protocol + * type to check validity with or the exclusion. For now only check on + * the parsing validity it will fail later on. + * */ + ret_size = uri_parse(url, &uri); + if (ret_size < 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + if (uri[0].port == 0) { + uri[0].port = DEFAULT_NETWORK_DATA_PORT; + } + + url_str = zmalloc(PATH_MAX); + if (!url_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + tmp = uri_to_str_url(&uri[0], url_str, PATH_MAX); + if (tmp < 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + raw_str = strndup(url, PATH_MAX); + if (!raw_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + /* Squash old value if any */ + free(attr->override_attr.data_url); + free(attr->raw_override_data_url); + + /* Populate the object */ + attr->override_attr.data_url = url_str; + attr->raw_override_data_url = raw_str; + + url_str = NULL; + raw_str = NULL; +end: + free(raw_str); + free(url_str); + free(uri); + return ret; +} + +int lttng_load_session_attr_set_override_url( + struct lttng_load_session_attr *attr, const char *url) +{ + int ret = 0; + ssize_t ret_size; + struct lttng_uri *uri = NULL; + char *raw_url_str = NULL; + char *raw_path_str = NULL; + char *path_str = NULL; + char *raw_ctrl_str = NULL; + char *ctrl_str = NULL; + char *raw_data_str = NULL; + char *data_str = NULL; + char buffer[PATH_MAX]; + int tmp = 0; + + if (!attr) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + + /* + * FIXME: uri_parse should be able to take as parameter the protocol + * type to check validity with or the exclusion. For now only check on + * the parsing validity it will fail later on. + * */ + ret_size = uri_parse_str_urls(url, NULL, &uri); + if (ret_size < 0 || ret_size > 2) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + raw_url_str = strndup(url, PATH_MAX); + if (!raw_url_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + /* Fetch path | ctrl && data string url */ + tmp = uri_to_str_url(&uri[0], buffer, sizeof(buffer)); + if (tmp < 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + switch (uri[0].dtype) { + case LTTNG_DST_PATH: + raw_path_str = strndup(buffer, PATH_MAX); + if (!raw_path_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + path_str = strndup(raw_path_str, PATH_MAX); + if (!path_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + break; + case LTTNG_DST_IPV4: + case LTTNG_DST_IPV6: + if (ret_size != 2) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + raw_ctrl_str = strndup(buffer, PATH_MAX); + if (!raw_ctrl_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + ctrl_str = strndup(raw_ctrl_str, PATH_MAX); + if (!ctrl_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + /* Fetch the data uri */ + tmp = uri_to_str_url(&uri[1], buffer, sizeof(buffer)); + if (tmp < 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + raw_data_str = strndup(buffer, PATH_MAX); + if (!raw_data_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + data_str = strndup(raw_data_str, PATH_MAX); + if (!data_str) { + /* FIXME: return valid error */ + ret = LTTNG_ERR_INVALID; + goto end; + } + + break; + default: + ret = -LTTNG_ERR_INVALID; + goto end; + } + + free(attr->override_attr.path_url); + free(attr->override_attr.ctrl_url); + free(attr->override_attr.data_url); + free(attr->raw_override_url); + free(attr->raw_override_path_url); + free(attr->raw_override_ctrl_url); + free(attr->raw_override_data_url); + + attr->override_attr.path_url = path_str; + attr->override_attr.ctrl_url = ctrl_str; + attr->override_attr.data_url = data_str; + + attr->raw_override_url = raw_url_str; + attr->raw_override_path_url = raw_path_str; + attr->raw_override_ctrl_url = raw_ctrl_str; + attr->raw_override_data_url = raw_data_str; + + /* Pass data responsability to the struct */ + raw_url_str = NULL; + raw_path_str = NULL; + path_str = NULL; + raw_ctrl_str = NULL; + ctrl_str = NULL; + raw_data_str = NULL; + data_str = NULL; + +end: + free(raw_path_str); + free(path_str); + free(raw_ctrl_str); + free(ctrl_str); + free(raw_data_str); + free(data_str); + free(raw_url_str); + free(uri); + return ret; +} /* * The lttng-ctl API does not expose all the information needed to load the * session configurations. Thus, we must send a load command to the session