#include <common/error.h>
#include <common/macros.h>
#include <common/utils.h>
-#include <common/config/config-session-internal.h>
#include <lttng/lttng-error.h>
#include <libxml/parser.h>
#include <libxml/valid.h>
const char * const config_event_context_pthread_id = "PTHREAD_ID";
const char * const config_event_context_hostname = "HOSTNAME";
const char * const config_event_context_ip = "IP";
+const char * const config_event_context_perf_thread_counter = "PERF_THREAD_COUNTER";
struct consumer_output {
int enabled;
config_entry_handler_cb handler, void *user_data)
{
int ret = 0;
+ char *path;
FILE *config_file = NULL;
struct handler_filter_args filter = { section, handler, user_data };
+ /* First, try system-wide conf. file. */
+ path = DEFAULT_DAEMON_SYSTEM_CONFIGPATH;
+
+ config_file = fopen(path, "r");
+ if (config_file) {
+ DBG("Loading daemon conf file at %s", path);
+ /*
+ * Return value is not very important here since error or not, we
+ * continue and try the next possible conf. file.
+ */
+ (void) ini_parse_file(config_file,
+ (ini_entry_handler) config_entry_handler_filter,
+ (void *) &filter);
+ fclose(config_file);
+ }
+
+ /* Second is the user local configuration. */
+ path = utils_get_home_dir();
+ if (path) {
+ char fullpath[PATH_MAX];
+
+ ret = snprintf(fullpath, sizeof(fullpath),
+ DEFAULT_DAEMON_HOME_CONFIGPATH, path);
+ if (ret < 0) {
+ PERROR("snprintf user conf. path");
+ goto error;
+ }
+
+ config_file = fopen(fullpath, "r");
+ if (config_file) {
+ DBG("Loading daemon user conf file at %s", path);
+ /*
+ * Return value is not very important here since error or not, we
+ * continue and try the next possible conf. file.
+ */
+ (void) ini_parse_file(config_file,
+ (ini_entry_handler) config_entry_handler_filter,
+ (void *) &filter);
+ fclose(config_file);
+ }
+ }
+
+ /* Final path is the one that the user might have provided. */
if (override_path) {
config_file = fopen(override_path, "r");
if (config_file) {
- DBG("Loaded daemon configuration file at %s",
- override_path);
+ DBG("Loading daemon command line conf file at %s", override_path);
+ (void) ini_parse_file(config_file,
+ (ini_entry_handler) config_entry_handler_filter,
+ (void *) &filter);
+ fclose(config_file);
} else {
ERR("Failed to open daemon configuration file at %s",
override_path);
ret = -ENOENT;
- goto end;
- }
- } else {
- char *path = utils_get_home_dir();
-
- /* Try to open the user's daemon configuration file */
- if (path) {
- ret = asprintf(&path, DEFAULT_DAEMON_HOME_CONFIGPATH, path);
- if (ret < 0) {
- goto end;
- }
-
- ret = 0;
- config_file = fopen(path, "r");
- if (config_file) {
- DBG("Loaded daemon configuration file at %s", path);
- }
-
- free(path);
- }
-
- /* Try to open the system daemon configuration file */
- if (!config_file) {
- config_file = fopen(DEFAULT_DAEMON_HOME_CONFIGPATH, "r");
+ goto error;
}
}
- if (!config_file) {
- DBG("No daemon configuration file found.");
- goto end;
- }
-
- ret = ini_parse_file(config_file,
- (ini_entry_handler) config_entry_handler_filter, (void *) &filter);
+ /* Everything went well. */
+ ret = 0;
-end:
+error:
return ret;
}
memset(ctx, 0, sizeof(struct session_config_validation_ctx));
}
+static
+char *get_session_config_xsd_path()
+{
+ char *xsd_path;
+ const char *base_path = getenv(DEFAULT_SESSION_CONFIG_XSD_PATH_ENV);
+ size_t base_path_len;
+ size_t max_path_len;
+
+ if (!base_path) {
+ base_path = DEFAULT_SESSION_CONFIG_XSD_PATH;
+ }
+
+ base_path_len = strlen(base_path);
+ max_path_len = base_path_len +
+ sizeof(DEFAULT_SESSION_CONFIG_XSD_FILENAME) + 1;
+ xsd_path = zmalloc(max_path_len);
+ if (!xsd_path) {
+ goto end;
+ }
+
+ strncpy(xsd_path, base_path, max_path_len);
+ if (xsd_path[base_path_len - 1] != '/') {
+ xsd_path[base_path_len++] = '/';
+ }
+
+ strncpy(xsd_path + base_path_len, DEFAULT_SESSION_CONFIG_XSD_FILENAME,
+ max_path_len - base_path_len);
+end:
+ return xsd_path;
+}
+
static
int init_session_config_validation_ctx(
struct session_config_validation_ctx *ctx)
{
int ret;
+ char *xsd_path = get_session_config_xsd_path();
+
+ if (!xsd_path) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
- ctx->parser_ctx = xmlSchemaNewParserCtxt(DEFAULT_SESSION_CONFIG_XSD_PATH);
+ ctx->parser_ctx = xmlSchemaNewParserCtxt(xsd_path);
if (!ctx->parser_ctx) {
ERR("XSD parser context creation failed");
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
fini_session_config_validation_ctx(ctx);
}
+ free(xsd_path);
return ret;
}
xmlNodePtr consumer_output_node;
assert(name);
- assert(kernel_domain);
- assert(ust_domain);
- assert(jul_domain);
if (output_node) {
consumer_output_node = xmlFirstElementChild(output_node);
/* network destination */
if (live_timer_interval && live_timer_interval != UINT64_MAX) {
- const char *url = output.control_uri ?
- output.control_uri : output.data_uri;
-
- /* URL has to be provided, even if we'll overwrite it after. */
- ret = lttng_create_session_live(name, url, live_timer_interval);
+ /*
+ * URLs are provided for sure since the test above make sure that
+ * with a live timer the data and control URIs are provided. So,
+ * NULL is passed here and will be set right after.
+ */
+ ret = lttng_create_session_live(name, NULL, live_timer_interval);
} else {
ret = lttng_create_session(name, NULL);
}
xmlChar *node_content = xmlNodeGetContent(node);
if (!node_content) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
name = (char *) node_content;
xmlChar *node_content = xmlNodeGetContent(node);
if (!node_content) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
ret = parse_bool(node_content, &started);
free(node_content);
if (ret) {
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
} else if (!output_node && !strcmp((const char *) node->name,
config_element_output)) {
xmlNodeGetContent(attributes_child);
if (!snapshot_mode_content) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
ret = parse_bool(snapshot_mode_content, &snapshot_mode);
free(snapshot_mode_content);
if (ret) {
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
} else {
/* live_timer_interval */
xmlNodeGetContent(attributes_child);
if (!timer_interval_content) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
ret = parse_uint(timer_interval_content, &live_timer_interval);
free(timer_interval_content);
if (ret) {
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
}
}
if (!name) {
/* Mandatory attribute, as defined in the session XSD */
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
if (session_name && strcmp(name, session_name)) {
/* This is not the session we are looking for */
- ret = -LTTNG_ERR_LOAD_SESSION_NOT_FOUND;
- goto end;
+ ret = -LTTNG_ERR_NO_SESSION;
+ goto error;
}
/* Init domains to create the session handles */
domain = zmalloc(sizeof(*domain));
if (!domain) {
ret = -LTTNG_ERR_NOMEM;
- goto end;
+ goto error;
}
ret = init_domain(node, domain);
domain_init_error:
free(domain);
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
+ goto error;
}
if (override) {
ret = lttng_destroy_session(name);
if (ret && ret != -LTTNG_ERR_SESS_NOT_FOUND) {
ERR("Failed to destroy existing session.");
- goto end;
+ goto error;
}
}
ret = create_session(name, kernel_domain, ust_domain, jul_domain,
output_node, UINT64_MAX);
}
-
if (ret) {
- goto end;
+ goto error;
}
for (node = xmlFirstElementChild(domains_node); node;
goto end;
}
}
+
end:
+ if (ret < 0) {
+ ERR("Failed to load session %s: %s", name, lttng_strerror(ret));
+ lttng_destroy_session(name);
+ }
+
+error:
free(kernel_domain);
free(ust_domain);
free(jul_domain);
end:
xmlFreeDoc(doc);
if (!ret) {
- ret = session_found ? 0 : -LTTNG_ERR_LOAD_SESSION_NOT_FOUND;
+ ret = session_found ? 0 : -LTTNG_ERR_LOAD_SESSION_NOENT;
}
return ret;
}
struct session_config_validation_ctx *validation_ctx, int override)
{
int ret, session_found = !session_name;
- struct stat sb;
DIR *directory = NULL;
assert(path);
assert(validation_ctx);
- ret = stat(path, &sb);
- if (ret) {
- ret = -LTTNG_ERR_LOAD_SESSION_NOENT;
- goto end;
+ directory = opendir(path);
+ if (!directory) {
+ switch (errno) {
+ case ENOTDIR:
+ /* Try the file loading. */
+ break;
+ case ENOENT:
+ ret = -LTTNG_ERR_LOAD_SESSION_NOENT;
+ goto end;
+ default:
+ ret = -LTTNG_ERR_LOAD_IO_FAIL;
+ goto end;
+ }
}
- if (S_ISDIR(sb.st_mode)) {
+ if (directory) {
struct dirent *entry;
struct dirent *result;
char *file_path = NULL;
goto end;
}
- directory = opendir(path);
- if (!directory) {
- ret = -LTTNG_ERR_LOAD_IO_FAIL;
- free(entry);
- goto end;
- }
-
file_path = zmalloc(PATH_MAX);
if (!file_path) {
ret = -LTTNG_ERR_NOMEM;
file_path[path_len++] = '/';
}
+ ret = 0;
/* Search for *.lttng files */
while (!readdir_r(directory, entry, &result) && result) {
size_t file_name_len = strlen(result->d_name);
continue;
}
- if (path_len + file_name_len > PATH_MAX) {
+ if (path_len + file_name_len >= PATH_MAX) {
continue;
}
}
if (!session_found) {
- ret = -LTTNG_ERR_LOAD_SESSION_NOT_FOUND;
+ ret = -LTTNG_ERR_LOAD_SESSION_NOENT;
}
return ret;
goto end;
}
- ret = load_session_from_path(path, NULL,
- &validation_ctx, 0);
- if (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT) {
+ ret = load_session_from_path(path, session_name,
+ &validation_ctx, override);
+ if (!ret || (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT)) {
+ /* Session found or an error occured */
free(path);
goto end;
}
}
/* Try system session configuration path */
- ret = load_session_from_path(DEFAULT_SESSION_SYSTEM_CONFIGPATH, NULL,
- &validation_ctx, 0);
- if (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT) {
+ ret = load_session_from_path(DEFAULT_SESSION_SYSTEM_CONFIGPATH,
+ session_name, &validation_ctx, override);
+ if (!ret || (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT)) {
+ /* Session found or an error occured */
goto end;
}
} else {
}
end:
fini_session_config_validation_ctx(&validation_ctx);
+ if (ret == -LTTNG_ERR_LOAD_SESSION_NOENT && !session_name && !path) {
+ /*
+ * Don't report an error if no sessions are found when called
+ * without a session_name or a search path.
+ */
+ ret = 0;
+ }
return ret;
}