#include <libxml/tree.h>
#include <lttng/lttng.h>
#include <lttng/snapshot.h>
+#include <lttng/rotation.h>
#include "session-config.h"
#include "config-internal.h"
const char * const config_element_num_subbuf = "subbuffer_count";
const char * const config_element_switch_timer_interval = "switch_timer_interval";
const char * const config_element_read_timer_interval = "read_timer_interval";
+LTTNG_HIDDEN const char * const config_element_monitor_timer_interval = "monitor_timer_interval";
+LTTNG_HIDDEN const char * const config_element_blocking_timeout = "blocking_timeout";
const char * const config_element_output = "output";
const char * const config_element_output_type = "output_type";
const char * const config_element_tracefile_size = "tracefile_size";
const char * const config_element_targets = "targets";
const char * const config_element_target_pid = "pid_target";
+LTTNG_HIDDEN const char * const config_element_rotation_timer_interval = "rotation_schedule_timer_period";
+LTTNG_HIDDEN const char * const config_element_rotation_schedule = "rotation_schedule";
+
const char * const config_domain_type_kernel = "KERNEL";
const char * const config_domain_type_ust = "UST";
const char * const config_domain_type_jul = "JUL";
}
static
-int create_snapshot_session(const char *session_name, xmlNodePtr output_node)
+int create_snapshot_session(const char *session_name, xmlNodePtr output_node,
+ const struct config_load_session_override_attr *overrides)
{
int ret;
xmlNodePtr node = NULL;
uint64_t max_size = UINT64_MAX;
struct consumer_output output = { 0 };
struct lttng_snapshot_output *snapshot_output = NULL;
+ const char *control_uri = NULL;
+ const char *data_uri = NULL;
+ const char *path = NULL;
for (node = xmlFirstElementChild(snapshot_output_node); node;
node = xmlNextElementSibling(node)) {
}
}
+ control_uri = output.control_uri;
+ data_uri = output.data_uri;
+ path = output.path;
+
+ if (overrides) {
+ if (overrides->path_url) {
+ path = overrides->path_url;
+ /* Control/data_uri are null */
+ control_uri = NULL;
+ data_uri = NULL;
+ } else {
+ if (overrides->ctrl_url) {
+ control_uri = overrides->ctrl_url;
+ /* path is null */
+ path = NULL;
+ }
+ if (overrides->data_url) {
+ data_uri = overrides->data_url;
+ /* path is null */
+ path = NULL;
+ }
+ }
+ }
+
snapshot_output = lttng_snapshot_output_create();
if (!snapshot_output) {
ret = -LTTNG_ERR_NOMEM;
goto error_snapshot_output;
}
- if (output.path) {
- ret = lttng_snapshot_output_set_ctrl_url(output.path,
+ if (path) {
+ ret = lttng_snapshot_output_set_ctrl_url(path,
snapshot_output);
if (ret) {
goto error_snapshot_output;
}
} else {
- if (output.control_uri) {
- ret = lttng_snapshot_output_set_ctrl_url(output.control_uri,
+ if (control_uri) {
+ ret = lttng_snapshot_output_set_ctrl_url(control_uri,
snapshot_output);
if (ret) {
goto error_snapshot_output;
}
}
- if (output.data_uri) {
- ret = lttng_snapshot_output_set_data_url(output.data_uri,
+ if (data_uri) {
+ ret = lttng_snapshot_output_set_data_url(data_uri,
snapshot_output);
if (ret) {
goto error_snapshot_output;
struct lttng_domain *jul_domain,
struct lttng_domain *log4j_domain,
xmlNodePtr output_node,
- uint64_t live_timer_interval)
+ uint64_t live_timer_interval,
+ const struct config_load_session_override_attr *overrides)
{
int ret;
struct consumer_output output = { 0 };
xmlNodePtr consumer_output_node;
+ const char *control_uri = NULL;
+ const char *data_uri = NULL;
+ const char *path = NULL;
assert(name);
}
}
- if (live_timer_interval != UINT64_MAX &&
- !output.control_uri && !output.data_uri) {
+ control_uri = output.control_uri;
+ data_uri = output.data_uri;
+ path = output.path;
+
+ /* Check for override and apply them */
+ if (overrides) {
+ if (overrides->path_url) {
+ path = overrides->path_url;
+ /* control/data_uri are null */;
+ control_uri = NULL;
+ data_uri = NULL;
+ } else {
+ if (overrides->ctrl_url) {
+ control_uri = overrides->ctrl_url;
+ /* path is null */
+ path = NULL;
+ }
+ if (overrides->data_url) {
+ data_uri = overrides->data_url;
+ /* path is null */
+ path = NULL;
+ }
+ }
+ }
+
+
+ if (live_timer_interval != UINT64_MAX && !control_uri && !data_uri) {
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
goto end;
}
- if (output.control_uri || output.data_uri) {
+ if (control_uri || data_uri) {
/* network destination */
if (live_timer_interval && live_timer_interval != UINT64_MAX) {
/*
goto end;
}
- ret = create_session_net_output(name, output.control_uri,
- output.data_uri);
+ ret = create_session_net_output(name, control_uri, data_uri);
if (ret) {
goto end;
}
} else {
/* either local output or no output */
- ret = lttng_create_session(name, output.path);
+ ret = lttng_create_session(name, path);
if (ret) {
goto end;
}
channel->attr.live_timer_interval =
live_timer_interval;
+ } else if (!strcmp((const char *) attr_node->name,
+ config_element_monitor_timer_interval)) {
+ xmlChar *content;
+ uint64_t monitor_timer_interval = 0;
+
+ /* monitor_timer_interval */
+ content = xmlNodeGetContent(attr_node);
+ if (!content) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ ret = parse_uint(content, &monitor_timer_interval);
+ free(content);
+ if (ret) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
+ ret = lttng_channel_set_monitor_timer_interval(channel,
+ monitor_timer_interval);
+ if (ret) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+ } else if (!strcmp((const char *) attr_node->name,
+ config_element_blocking_timeout)) {
+ xmlChar *content;
+ int64_t blocking_timeout = 0;
+
+ /* blocking_timeout */
+ content = xmlNodeGetContent(attr_node);
+ if (!content) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ ret = parse_int(content, &blocking_timeout);
+ free(content);
+ if (ret) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
+ ret = lttng_channel_set_blocking_timeout(channel,
+ blocking_timeout);
+ if (ret) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
} else if (!strcmp((const char *) attr_node->name,
config_element_events)) {
/* events */
return ret;
}
-
static
int process_domain_node(xmlNodePtr domain_node, const char *session_name)
{
int ret;
struct lttng_domain domain = { 0 };
struct lttng_handle *handle = NULL;
+ struct lttng_channel *channel = NULL;
xmlNodePtr channels_node = NULL;
xmlNodePtr trackers_node = NULL;
xmlNodePtr pid_tracker_node = NULL;
/* create all channels */
for (node = xmlFirstElementChild(channels_node); node;
node = xmlNextElementSibling(node)) {
- struct lttng_channel channel;
xmlNodePtr contexts_node = NULL;
xmlNodePtr events_node = NULL;
xmlNodePtr channel_attr_node;
- memset(&channel, 0, sizeof(channel));
- lttng_channel_set_default_attr(&domain, &channel.attr);
+ channel = lttng_channel_create(&domain);
+ if (!channel) {
+ ret = -1;
+ goto end;
+ }
for (channel_attr_node = xmlFirstElementChild(node);
channel_attr_node; channel_attr_node =
xmlNextElementSibling(channel_attr_node)) {
ret = process_channel_attr_node(channel_attr_node,
- &channel, &contexts_node, &events_node);
+ channel, &contexts_node, &events_node);
if (ret) {
goto end;
}
}
- ret = lttng_enable_channel(handle, &channel);
+ ret = lttng_enable_channel(handle, channel);
if (ret < 0) {
goto end;
}
- ret = process_events_node(events_node, handle, channel.name);
+ ret = process_events_node(events_node, handle, channel->name);
if (ret) {
goto end;
}
ret = process_contexts_node(contexts_node, handle,
- channel.name);
+ channel->name);
if (ret) {
goto end;
}
+
+ lttng_channel_destroy(channel);
}
+ channel = NULL;
/* get the trackers node */
for (node = xmlFirstElementChild(domain_node); node;
}
end:
+ lttng_channel_destroy(channel);
lttng_destroy_handle(handle);
return ret;
}
static
int process_session_node(xmlNodePtr session_node, const char *session_name,
- int override)
+ int overwrite,
+ const struct config_load_session_override_attr *overrides)
{
int ret, started = -1, snapshot_mode = -1;
- uint64_t live_timer_interval = UINT64_MAX;
+ uint64_t live_timer_interval = UINT64_MAX,
+ rotation_timer_interval = 0;
xmlChar *name = NULL;
xmlChar *shm_path = NULL;
xmlNodePtr domains_node = NULL;
shm_path = node_content;
} else {
- /* attributes, snapshot_mode or live_timer_interval */
+ /*
+ * attributes, snapshot_mode, live_timer_interval, rotation_size,
+ * rotation_timer_interval. */
xmlNodePtr attributes_child =
xmlFirstElementChild(node);
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
goto error;
}
- } else {
+ } else if (!strcmp((const char *) attributes_child->name,
+ config_element_live_timer_interval)) {
/* live_timer_interval */
xmlChar *timer_interval_content =
xmlNodeGetContent(attributes_child);
goto error;
}
}
+ if (!strcmp((const char *) attributes_child->name,
+ config_element_rotation_timer_interval)) {
+ /* rotation_timer_interval */
+ xmlChar *timer_interval_content =
+ xmlNodeGetContent(attributes_child);
+ if (!timer_interval_content) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto error;
+ }
+
+ ret = parse_uint(timer_interval_content, &rotation_timer_interval);
+ free(timer_interval_content);
+ if (ret) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto error;
+ }
+ }
}
}
goto error;
}
- if (override) {
+ /* Apply overrides */
+ if (overrides) {
+ if (overrides->session_name) {
+ xmlChar *name_override = xmlStrdup(BAD_CAST(overrides->session_name));
+ if (!name_override) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto error;
+ }
+
+ /* Overrides the session name to the provided name */
+ xmlFree(name);
+ name = name_override;
+ }
+ }
+
+ if (overwrite) {
/* Destroy session if it exists */
ret = lttng_destroy_session((const char *) name);
if (ret && ret != -LTTNG_ERR_SESS_NOT_FOUND) {
/* Create session type depending on output type */
if (snapshot_mode && snapshot_mode != -1) {
- ret = create_snapshot_session((const char *) name, output_node);
+ ret = create_snapshot_session((const char *) name, output_node,
+ overrides);
} else if (live_timer_interval &&
live_timer_interval != UINT64_MAX) {
ret = create_session((const char *) name, kernel_domain,
ust_domain, jul_domain, log4j_domain,
- output_node, live_timer_interval);
+ output_node, live_timer_interval, overrides);
} else {
/* regular session */
ret = create_session((const char *) name, kernel_domain,
ust_domain, jul_domain, log4j_domain,
- output_node, UINT64_MAX);
+ output_node, UINT64_MAX, overrides);
}
if (ret) {
goto error;
}
}
+ if (rotation_timer_interval) {
+ struct lttng_rotation_schedule_attr *rotation_attr = lttng_rotation_schedule_attr_create();
+
+ if (!rotation_attr) {
+ goto error;
+ }
+ ret = lttng_rotation_schedule_attr_set_session_name(rotation_attr, (const char *) name);
+ if (ret) {
+ lttng_rotation_schedule_attr_destroy(rotation_attr);
+ goto error;
+ }
+ lttng_rotation_schedule_attr_set_timer_period(rotation_attr,
+ rotation_timer_interval);
+ ret = lttng_rotation_set_schedule(rotation_attr);
+ lttng_rotation_schedule_attr_destroy(rotation_attr);
+ if (ret) {
+ goto error;
+ }
+ }
+
if (started) {
ret = lttng_start_tracing((const char *) name);
if (ret) {
static
int load_session_from_file(const char *path, const char *session_name,
- struct session_config_validation_ctx *validation_ctx, int override)
+ struct session_config_validation_ctx *validation_ctx, int overwrite,
+ const struct config_load_session_override_attr *overrides)
{
int ret, session_found = !session_name;
xmlDocPtr doc = NULL;
session_node; session_node =
xmlNextElementSibling(session_node)) {
ret = process_session_node(session_node,
- session_name, override);
+ session_name, overwrite, overrides);
if (session_name && ret == 0) {
/* Target session found and loaded */
session_found = 1;
static
int load_session_from_path(const char *path, const char *session_name,
- struct session_config_validation_ctx *validation_ctx, int override)
+ struct session_config_validation_ctx *validation_ctx, int overwrite,
+ const struct config_load_session_override_attr *overrides)
{
int ret, session_found = !session_name;
DIR *directory = NULL;
file_path[path_len + file_name_len] = '\0';
ret = load_session_from_file(file_path, session_name,
- validation_ctx, override);
+ validation_ctx, overwrite, overrides);
if (session_name && !ret) {
session_found = 1;
break;
free(file_path);
} else {
ret = load_session_from_file(path, session_name,
- validation_ctx, override);
+ validation_ctx, overwrite, overrides);
if (ret) {
goto end;
} else {
if (errno != ENOENT) {
PERROR("stat");
}
- ret = -LTTNG_ERR_INVALID;
goto valid;
}
LTTNG_HIDDEN
int config_load_session(const char *path, const char *session_name,
- int override, unsigned int autoload)
+ int overwrite, unsigned int autoload,
+ const struct config_load_session_override_attr *overrides)
{
int ret;
bool session_loaded = false;
}
if (path_ptr) {
ret = load_session_from_path(path_ptr, session_name,
- &validation_ctx, override);
+ &validation_ctx, overwrite, overrides);
if (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT) {
goto end;
}
if (path_ptr) {
ret = load_session_from_path(path_ptr, session_name,
- &validation_ctx, override);
+ &validation_ctx, overwrite, overrides);
if (!ret) {
session_loaded = true;
}
}
ret = load_session_from_path(path, session_name,
- &validation_ctx, override);
+ &validation_ctx, overwrite, overrides);
}
end:
fini_session_config_validation_ctx(&validation_ctx);