#include <include/config.h>
#include <common/config/config.h>
+#include <lttng/snapshot-internal.h>
#include "mi-lttng.h"
#include <assert.h>
/* Strings related to command */
const char * const mi_lttng_element_command = "command";
-const char * const mi_lttng_element_command_name = "name";
-const char * const mi_lttng_element_command_version = "version";
+const char * const mi_lttng_element_command_action = "snapshot_action";
+const char * const mi_lttng_element_command_add_context = "add-context";
+const char * const mi_lttng_element_command_calibrate = "calibrate";
+const char * const mi_lttng_element_command_create = "create";
+const char * const mi_lttng_element_command_destroy = "destroy";
+const char * const mi_lttng_element_command_disable_channel = "disable-channel";
+const char * const mi_lttng_element_command_disable_event = "disable-event";
+const char * const mi_lttng_element_command_enable_channels = "enable-channel";
+const char * const mi_lttng_element_command_enable_event = "enable-event";
const char * const mi_lttng_element_command_list = "list";
-const char * const mi_lttng_element_command_save = "save";
const char * const mi_lttng_element_command_load = "load";
+const char * const mi_lttng_element_command_name = "name";
+const char * const mi_lttng_element_command_output = "output";
+const char * const mi_lttng_element_command_save = "save";
+const char * const mi_lttng_element_command_set_session = "set-session";
+const char * const mi_lttng_element_command_snapshot = "snapshot";
+const char * const mi_lttng_element_command_snapshot_add = "add_snapshot";
+const char * const mi_lttng_element_command_snapshot_del = "del_snapshot";
+const char * const mi_lttng_element_command_snapshot_list = "list_snapshot";
+const char * const mi_lttng_element_command_snapshot_record = "record_snapshot";
const char * const mi_lttng_element_command_start = "start";
const char * const mi_lttng_element_command_stop = "stop";
-const char * const mi_lttng_element_command_create = "create";
-const char * const mi_lttng_element_command_destroy = "destroy";
-const char * const mi_lttng_element_command_output = "output";
const char * const mi_lttng_element_command_success = "success";
+const char * const mi_lttng_element_command_version = "version";
/* Strings related to version command */
const char * const mi_lttng_element_version = "version";
-const char * const mi_lttng_element_version_str = "string";
-const char * const mi_lttng_element_version_web = "url";
-const char * const mi_lttng_element_version_major = "major";
-const char * const mi_lttng_element_version_minor = "minor";
const char * const mi_lttng_element_version_commit = "commit";
+const char * const mi_lttng_element_version_description = "description";
const char * const mi_lttng_element_version_license = "license";
+const char * const mi_lttng_element_version_major = "major";
+const char * const mi_lttng_element_version_minor = "minor";
const char * const mi_lttng_element_version_patch_level = "patchLevel";
-const char * const mi_lttng_element_version_description = "description";
+const char * const mi_lttng_element_version_str = "string";
+const char * const mi_lttng_element_version_web = "url";
+
+/* String related to a lttng_event_field */
+const char * const mi_lttng_element_event_field = "event_field";
+const char * const mi_lttng_element_event_fields = "event_fields";
+
+/* String related to lttng_event_context */
+const char * const mi_lttng_context_type_perf_counter = "PERF_COUNTER";
+const char * const mi_lttng_context_type_perf_cpu_counter = "PERF_CPU_COUNTER";
+const char * const mi_lttng_context_type_perf_thread_counter = "PERF_THREAD_COUNTER";
+
+/* String related to lttng_event_perf_counter_ctx */
+const char * const mi_lttng_element_perf_counter_context = "perf_counter_context";
/* Strings related to pid */
const char * const mi_lttng_element_pids = "pids";
/* Strings related to load command */
const char * const mi_lttng_element_load = "load";
-/* String related to a lttng_event_field */
-const char * const mi_lttng_element_event_field = "event_field";
-const char * const mi_lttng_element_event_fields = "event_fields";
-
/* General elements of mi_lttng */
-const char * const mi_lttng_element_type_other = "OTHER";
-const char * const mi_lttng_element_type_integer = "INTEGER";
+const char * const mi_lttng_element_empty = "";
+const char * const mi_lttng_element_id = "id";
+const char * const mi_lttng_element_nowrite = "nowrite";
+const char * const mi_lttng_element_success = "success";
const char * const mi_lttng_element_type_enum = "ENUM";
const char * const mi_lttng_element_type_float = "FLOAT";
+const char * const mi_lttng_element_type_integer = "INTEGER";
+const char * const mi_lttng_element_type_other = "OTHER";
const char * const mi_lttng_element_type_string = "STRING";
-const char * const mi_lttng_element_nowrite = "nowrite";
/* String related to loglevel */
const char * const mi_lttng_loglevel_str_alert = "TRACE_ALERT";
const char * const mi_lttng_loglevel_str_unknown = "UNKNOWN";
const char * const mi_lttng_loglevel_str_warning = "TRACE_WARNING";
+/* String related to loglevel JUL */
+const char * const mi_lttng_loglevel_str_jul_all = "JUL_ALL";
+const char * const mi_lttng_loglevel_str_jul_config = "JUL_CONFIG";
+const char * const mi_lttng_loglevel_str_jul_fine = "JUL_FINE";
+const char * const mi_lttng_loglevel_str_jul_finer = "JUL_FINER";
+const char * const mi_lttng_loglevel_str_jul_finest = "JUL_FINEST";
+const char * const mi_lttng_loglevel_str_jul_info = "JUL_INFO";
+const char * const mi_lttng_loglevel_str_jul_off = "JUL_OFF";
+const char * const mi_lttng_loglevel_str_jul_severe = "JUL_SEVERE";
+const char * const mi_lttng_loglevel_str_jul_warning = "JUL_WARNING";
+
/* String related to loglevel type */
const char * const mi_lttng_loglevel_type_all = "ALL";
const char * const mi_lttng_loglevel_type_range = "RANGE";
const char * const mi_lttng_loglevel_type_single = "SINGLE";
const char * const mi_lttng_loglevel_type_unknown = "UNKNOWN";
-const char * const mi_lttng_element_empty = "";
-
+/* String related to lttng_calibrate */
+const char * const mi_lttng_element_calibrate = "calibrate";
+const char * const mi_lttng_element_calibrate_function = "FUNCTION";
+
+/* String related to a lttng_snapshot_output */
+const char * const mi_lttng_element_snapshot_ctrl_url = "ctrl_url";
+const char * const mi_lttng_element_snapshot_data_url = "data_url";
+const char * const mi_lttng_element_snapshot_max_size = "max_size";
+const char * const mi_lttng_element_snapshot_n_ptr = "n_ptr";
+const char * const mi_lttng_element_snapshot_session_name = "session_name";
+const char * const mi_lttng_element_snapshots = "snapshots";
+
+/* This is a merge of jul loglevel and regular loglevel
+ * Those should never overlap by definition
+ * (see struct lttng_event loglevel)
+ */
const char *mi_lttng_loglevel_string(int value)
{
switch (value) {
return mi_lttng_loglevel_str_debug_line;
case LTTNG_LOGLEVEL_DEBUG:
return mi_lttng_loglevel_str_debug;
+ case LTTNG_LOGLEVEL_JUL_OFF:
+ return mi_lttng_loglevel_str_jul_off;
+ case LTTNG_LOGLEVEL_JUL_SEVERE:
+ return mi_lttng_loglevel_str_jul_severe;
+ case LTTNG_LOGLEVEL_JUL_WARNING:
+ return mi_lttng_loglevel_str_jul_warning;
+ case LTTNG_LOGLEVEL_JUL_INFO:
+ return mi_lttng_loglevel_str_jul_info;
+ case LTTNG_LOGLEVEL_JUL_CONFIG:
+ return mi_lttng_loglevel_str_jul_config;
+ case LTTNG_LOGLEVEL_JUL_FINE:
+ return mi_lttng_loglevel_str_jul_fine;
+ case LTTNG_LOGLEVEL_JUL_FINER:
+ return mi_lttng_loglevel_str_jul_finer;
+ case LTTNG_LOGLEVEL_JUL_FINEST:
+ return mi_lttng_loglevel_str_jul_finest;
+ case LTTNG_LOGLEVEL_JUL_ALL:
+ return mi_lttng_loglevel_str_jul_all;
default:
return mi_lttng_loglevel_str_unknown;
}
}
}
+const char *mi_lttng_event_contexttype_string(enum lttng_event_context_type val)
+{
+ switch (val) {
+ case LTTNG_EVENT_CONTEXT_PID:
+ return config_event_context_pid;
+ case LTTNG_EVENT_CONTEXT_PERF_COUNTER:
+ return mi_lttng_context_type_perf_counter;
+ case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
+ return mi_lttng_context_type_perf_thread_counter;
+ case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER:
+ return mi_lttng_context_type_perf_cpu_counter;
+ case LTTNG_EVENT_CONTEXT_PROCNAME:
+ return config_event_context_procname;
+ case LTTNG_EVENT_CONTEXT_PRIO:
+ return config_event_context_prio;
+ case LTTNG_EVENT_CONTEXT_NICE:
+ return config_event_context_nice;
+ case LTTNG_EVENT_CONTEXT_VPID:
+ return config_event_context_vpid;
+ case LTTNG_EVENT_CONTEXT_TID:
+ return config_event_context_tid;
+ case LTTNG_EVENT_CONTEXT_VTID:
+ return config_event_context_vtid;
+ case LTTNG_EVENT_CONTEXT_PPID:
+ return config_event_context_ppid;
+ case LTTNG_EVENT_CONTEXT_VPPID:
+ return config_event_context_vppid;
+ case LTTNG_EVENT_CONTEXT_PTHREAD_ID:
+ return config_event_context_pthread_id;
+ case LTTNG_EVENT_CONTEXT_HOSTNAME:
+ return config_event_context_hostname;
+ case LTTNG_EVENT_CONTEXT_IP:
+ return config_event_context_ip;
+ default:
+ return NULL;
+ }
+}
+
const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type val)
{
switch (val) {
}
}
+const char *mi_lttng_calibratetype_string(enum lttng_calibrate_type val)
+{
+ const char *ret;
+
+ switch (val) {
+ case LTTNG_CALIBRATE_FUNCTION:
+ ret = mi_lttng_element_calibrate_function;
+ break;
+ default:
+ ret = mi_lttng_element_empty;
+ break;
+ }
+ return ret;
+}
+
LTTNG_HIDDEN
struct mi_writer *mi_lttng_writer_create(int fd_output, int mi_output_type)
{
/* Version string (contain info like rc etc.) */
ret = mi_lttng_writer_write_element_string(writer,
- mi_lttng_element_version_str, VERSION);
+ mi_lttng_element_version_str, version->version);
if (ret) {
goto end;
}
goto end;
}
- /* TODO: attr... not sure how to use the union.... */
+ /* TODO: union attr
+ * This union is not currently used and was added for
+ * future ust domain support.
+ * Date: 25-06-2014
+ * */
if (!is_open) {
/* Closing domain element */
goto end;
}
- /* event name */
+ /* Event name */
ret = mi_lttng_writer_write_element_string(writer,
config_element_name, event->name);
if (ret) {
goto end;
}
- /* event type */
+ /* Event type */
ret = mi_lttng_writer_write_element_string(writer,
config_element_type, mi_lttng_eventtype_string(event->type));
if (ret) {
goto end;
}
- /* is event enabled */
+ /* Is event enabled */
ret = mi_lttng_writer_write_element_bool(writer,
config_element_enabled, event->enabled);
if (ret) {
goto end;
}
- /* event filter enabled? */
+ /* Event filter enabled? */
ret = mi_lttng_writer_write_element_bool(writer,
config_element_filter, event->filter);
{
int ret;
- /* event loglevel */
+ /* Event loglevel */
ret = mi_lttng_writer_write_element_string(writer,
config_element_loglevel, mi_lttng_loglevel_string(event->loglevel));
if (ret) {
goto end;
}
+ /* Log level type */
ret = mi_lttng_writer_write_element_string(writer,
config_element_loglevel_type,
mi_lttng_logleveltype_string(event->loglevel_type));
}
switch (event->type) {
- case LTTNG_EVENT_ALL:
- /* We should never have "all" events in list. */
- assert(0);
- break;
case LTTNG_EVENT_TRACEPOINT:
{
if (event->loglevel != -1) {
case LTTNG_EVENT_FUNCTION_ENTRY:
ret = mi_lttng_event_function_entry(writer, event);
break;
+ case LTTNG_EVENT_ALL:
+ /* Fallthrough */
default:
break;
}
int ret;
if (!field->field_name[0]) {
- /* To Review: not sure if legal david ?
- * how should this be handle ?
- */
ret = 0;
goto end;
}
end:
return ret;
}
+
+LTTNG_HIDDEN
+int mi_lttng_calibrate(struct mi_writer *writer,
+ struct lttng_calibrate *calibrate)
+{
+ int ret;
+
+ /* Open calibrate element */
+ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_calibrate);
+ if (ret) {
+ goto end;
+ }
+
+ /* Calibration type */
+ ret = mi_lttng_writer_write_element_string(writer, config_element_type,
+ mi_lttng_calibratetype_string(calibrate->type));
+ if (ret) {
+ goto end;
+ }
+
+ /* Closing calibrate element */
+ ret = mi_lttng_writer_close_element(writer);
+end:
+ return ret;
+}
+LTTNG_HIDDEN
+int mi_lttng_context(struct mi_writer *writer,
+ struct lttng_event_context *context, int is_open)
+{
+ int ret;
+ const char *type_string;
+ struct lttng_event_perf_counter_ctx *perf_context;
+ /* Open context */
+ ret = mi_lttng_writer_open_element(writer , config_element_context);
+ if (ret) {
+ goto end;
+ }
+
+ type_string = mi_lttng_event_contexttype_string(context->ctx);
+ if (!type_string) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ /* Print context type */
+ ret = mi_lttng_writer_write_element_string(writer, config_element_type,
+ type_string);
+
+ /* Special case for PERF_*_COUNTER
+ * print the lttng_event_perf_counter_ctx*/
+ switch (context->ctx) {
+ case LTTNG_EVENT_CONTEXT_PERF_COUNTER:
+ case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
+ case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER:
+ perf_context = &context->u.perf_counter;
+ ret = mi_lttng_perf_counter_context(writer, perf_context);
+ if (ret) {
+ goto end;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Close context */
+ if (!is_open) {
+ ret = mi_lttng_writer_close_element(writer);
+ }
+
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int mi_lttng_perf_counter_context(struct mi_writer *writer,
+ struct lttng_event_perf_counter_ctx *perf_context)
+{
+ int ret;
+
+ /* Open perf_counter_context */
+ ret = mi_lttng_writer_open_element(writer,
+ mi_lttng_element_perf_counter_context);
+ if (ret) {
+ goto end;
+ }
+
+ /* Type */
+ ret = mi_lttng_writer_write_element_unsigned_int(writer,
+ config_element_type, perf_context->type);
+ if (ret) {
+ goto end;
+ }
+
+ /* Config */
+ ret = mi_lttng_writer_write_element_unsigned_int(writer,
+ config_element_config, perf_context->config);
+ if (ret) {
+ goto end;
+ }
+
+ /* Name of the perf counter */
+ ret = mi_lttng_writer_write_element_string(writer,
+ config_element_name, perf_context->name);
+ if (ret) {
+ goto end;
+ }
+
+ /* Close perf_counter_context */
+ ret = mi_lttng_writer_close_element(writer);
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int mi_lttng_snapshot_output_session_name(struct mi_writer *writer,
+ const char *session_name)
+{
+ int ret;
+
+ /* Open session element */
+ ret = mi_lttng_writer_open_element(writer, config_element_session);
+ if (ret) {
+ goto end;
+ }
+
+ /* Snapshot output list for current session name */
+ ret = mi_lttng_writer_write_element_string(writer, config_element_name,
+ session_name);
+
+ /* Open element snapshots (sequence one snapshot) */
+ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_snapshots);
+ if (ret) {
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int mi_lttng_snapshot_list_output(struct mi_writer *writer,
+ struct lttng_snapshot_output *output)
+{
+ int ret;
+
+ /* Open element snapshot output */
+ ret = mi_lttng_writer_open_element(writer,
+ mi_lttng_element_command_snapshot);
+ if (ret) {
+ goto end;
+ }
+
+ /* ID of the snapshot output */
+ ret = mi_lttng_writer_write_element_unsigned_int(writer,
+ mi_lttng_element_id, output->id);
+ if (ret) {
+ goto end;
+ }
+
+ /* Name of the output */
+ ret = mi_lttng_writer_write_element_string(writer, config_element_name,
+ output->name);
+ if (ret) {
+ goto end;
+ }
+
+ /* Destination of the output (ctrl_url)*/
+ ret = mi_lttng_writer_write_element_string(writer,
+ mi_lttng_element_snapshot_ctrl_url, output->ctrl_url);
+ if (ret) {
+ goto end;
+ }
+
+ /* Destination of the output (data_url) */
+ ret = mi_lttng_writer_write_element_string(writer,
+ mi_lttng_element_snapshot_data_url, output->data_url);
+ if (ret) {
+ goto end;
+ }
+
+ /* total size of all stream combined */
+ ret = mi_lttng_writer_write_element_unsigned_int(writer,
+ mi_lttng_element_snapshot_max_size, output->max_size);
+ if (ret) {
+ goto end;
+ }
+
+ /* Close snapshot output element */
+ ret = mi_lttng_writer_close_element(writer);
+
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int mi_lttng_snapshot_del_output(struct mi_writer *writer, int id,
+ const char *name, const char *current_session_name)
+{
+ int ret;
+
+ /* Open element del_snapshot */
+ ret = mi_lttng_writer_open_element(writer,
+ mi_lttng_element_command_snapshot);
+ if (ret) {
+ goto end;
+ }
+
+
+ if (id != UINT32_MAX) {
+ /* "Snapshot output "id" successfully deleted
+ * for "current_session_name"
+ * ID of the snapshot output
+ */
+ ret = mi_lttng_writer_write_element_unsigned_int(writer,
+ mi_lttng_element_id, id);
+ if (ret) {
+ goto end;
+ }
+ } else {
+ /* "Snapshot output "name" successfully deleted
+ * for session "current_session_name"
+ * Name of the output
+ */
+ ret = mi_lttng_writer_write_element_string(writer, config_element_name,
+ name);
+ if (ret) {
+ goto end;
+ }
+ }
+
+ /* Snapshot was deleted for session "current_session_name"*/
+ ret = mi_lttng_writer_write_element_string(writer,
+ mi_lttng_element_snapshot_session_name,
+ current_session_name);
+ if (ret) {
+ goto end;
+ }
+
+ /* Close snapshot element */
+ ret = mi_lttng_writer_close_element(writer);
+
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int mi_lttng_snapshot_add_output(struct mi_writer *writer,
+ const char *current_session_name, const char *n_ptr,
+ struct lttng_snapshot_output *output)
+{
+ int ret;
+
+ /* Open element snapshot */
+ ret = mi_lttng_writer_open_element(writer,
+ mi_lttng_element_command_snapshot);
+ if (ret) {
+ goto end;
+ }
+
+ /* Snapshot output id */
+ ret = mi_lttng_writer_write_element_unsigned_int(writer,
+ mi_lttng_element_id, output->id);
+ if (ret) {
+ goto end;
+ }
+
+ /* Snapshot output names */
+ ret = mi_lttng_writer_write_element_string(writer,
+ config_element_name, n_ptr);
+ if (ret) {
+ goto end;
+ }
+
+ /* Destination of the output (ctrl_url)*/
+ ret = mi_lttng_writer_write_element_string(writer,
+ mi_lttng_element_snapshot_ctrl_url, output->ctrl_url);
+ if (ret) {
+ goto end;
+ }
+
+ /* Snapshot added for session "current_session_name"*/
+ ret = mi_lttng_writer_write_element_string(writer,
+ mi_lttng_element_snapshot_session_name, current_session_name);
+ if (ret) {
+ goto end;
+ }
+
+ /* total size of all stream combined */
+ ret = mi_lttng_writer_write_element_unsigned_int(writer,
+ mi_lttng_element_snapshot_max_size, output->max_size);
+ if (ret) {
+ goto end;
+ }
+
+ /* Close snapshot element */
+ ret = mi_lttng_writer_close_element(writer);
+
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int mi_lttng_snapshot_record(struct mi_writer *writer,
+ const char *current_session_name, const char *url,
+ const char *cmdline_ctrl_url, const char *cmdline_data_url)
+{
+ int ret;
+
+ /* Open element snapshot */
+ ret = mi_lttng_writer_open_element(writer,
+ mi_lttng_element_command_snapshot);
+ if (ret) {
+ goto end;
+ }
+
+ /*
+ * If a valid an URL was given, serialize it,
+ * else take the command line data and ctrl urls*/
+ if (url) {
+ /* Destination of the output (ctrl_url)*/
+ ret = mi_lttng_writer_write_element_string(writer,
+ mi_lttng_element_snapshot_ctrl_url, url);
+ if (ret) {
+ goto end;
+ }
+ } else if (cmdline_ctrl_url) {
+ /* Destination of the output (ctrl_url)*/
+ ret = mi_lttng_writer_write_element_string(writer,
+ mi_lttng_element_snapshot_ctrl_url, cmdline_ctrl_url);
+ if (ret) {
+ goto end;
+ }
+
+ /* Destination of the output (data_url) */
+ ret = mi_lttng_writer_write_element_string(writer,
+ mi_lttng_element_snapshot_data_url, cmdline_data_url);
+ if (ret) {
+ goto end;
+ }
+ }
+
+ /* Close record_snapshot element */
+ ret = mi_lttng_writer_close_element(writer);
+
+end:
+ return ret;
+}