#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <assert.h>
+
+#include <common/mi-lttng.h>
#include "../command.h"
};
static struct lttng_handle *handle;
+static struct mi_writer *writer;
static struct poptOption long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
fprintf(ofp, "\n");
}
+static int mi_partial_channel_print(char *channel_name, unsigned int enabled,
+ int success)
+{
+ int ret;
+
+ assert(writer);
+ assert(channel_name);
+
+ /* Open channel element */
+ ret = mi_lttng_writer_open_element(writer, config_element_channel);
+ if (ret) {
+ goto end;
+ }
+
+ /* Name */
+ ret = mi_lttng_writer_write_element_string(writer, config_element_name,
+ channel_name);
+ if (ret) {
+ goto end;
+ }
+
+ /* Enabled ? */
+ ret = mi_lttng_writer_write_element_bool(writer, config_element_enabled,
+ enabled);
+ if (ret) {
+ goto end;
+ }
+
+ /* Success ? */
+ ret = mi_lttng_writer_write_element_bool(writer,
+ mi_lttng_element_command, success);
+ if (ret) {
+ goto end;
+ }
+
+ /* Closing channel element */
+ ret = mi_lttng_writer_close_element(writer);
+
+end:
+ return ret;
+}
+
/*
* Disabling channel using the lttng API.
*/
static int disable_channels(char *session_name)
{
- int ret = CMD_SUCCESS, warn = 0;
+ int ret = CMD_SUCCESS, warn = 0, success;
+
+ /* Normal case for disable channed is enabled = 0 */
+ unsigned int enabled = 0;
char *channel_name;
struct lttng_domain dom;
goto error;
}
+ /* Prepare MI */
+ if (lttng_opt_mi) {
+ /* open a channels element */
+ ret = mi_lttng_writer_open_element(writer, config_element_channels);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto error;
+ }
+
+ }
+
/* Strip channel list */
channel_name = strtok(opt_channels, ",");
while (channel_name != NULL) {
ERR("Channel %s: %s (session %s)", channel_name,
lttng_strerror(ret), session_name);
warn = 1;
+
+ /*
+ * Mi:
+ * We assume that if an error occurred the channel is still active.
+ * This might not be the case but is a good assumption.
+ * The client should look at the stderr stream for more informations.
+ */
+ enabled = 1;
+ success = 0;
+
} else {
MSG("%s channel %s disabled for session %s",
get_domain_str(dom.type), channel_name, session_name);
+ enabled = 0;
+ success = 1;
+ }
+
+ /* Print the channel */
+ if (lttng_opt_mi) {
+ ret = mi_partial_channel_print(channel_name, enabled, success);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto error;
+ }
}
/* Next channel */
ret = CMD_SUCCESS;
+ /* Close Mi */
+ if (lttng_opt_mi) {
+ /* Close channels element */
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto error;
+ }
+ }
+
error:
- if (warn) {
+ /* Bypass the warning if a more important error happened */
+ if (!ret && warn) {
ret = CMD_WARNING;
}
*/
int cmd_disable_channels(int argc, const char **argv)
{
- int opt, ret = CMD_SUCCESS;
+ int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
static poptContext pc;
char *session_name = NULL;
}
}
- /* TODO: mi support */
- if (lttng_opt_mi) {
- ret = -LTTNG_ERR_MI_NOT_IMPLEMENTED;
- ERR("mi option not supported");
- goto end;
- }
-
opt_channels = (char*) poptGetArg(pc);
if (opt_channels == NULL) {
ERR("Missing channel name(s).\n");
session_name = opt_session_name;
}
- ret = disable_channels(session_name);
+ /* Mi check */
+ if (lttng_opt_mi) {
+ writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
+ if (!writer) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ /* Open command element */
+ ret = mi_lttng_writer_command_open(writer,
+ mi_lttng_element_command_disable_channel);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ /* Open output element */
+ ret = mi_lttng_writer_open_element(writer,
+ mi_lttng_element_command_output);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+ }
+
+ command_ret = disable_channels(session_name);
+ if (command_ret) {
+ success = 0;
+ }
+
+ /* Mi closing */
+ if (lttng_opt_mi) {
+ /* Close output element */
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ /* Success ? */
+ ret = mi_lttng_writer_write_element_bool(writer,
+ mi_lttng_element_success, success);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ /* Command element close */
+ ret = mi_lttng_writer_command_close(writer);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+ }
end:
+ /* Mi clean-up */
+ if (writer && mi_lttng_writer_destroy(writer)) {
+ /* Preserve original error code */
+ ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
+ }
+
if (!opt_session_name && session_name) {
free(session_name);
}
+
+ /* Overwrite ret if an error occurred in disable_channels */
+ ret = command_ret ? command_ret : ret;
+
poptFreeContext(pc);
return ret;
}
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <assert.h>
#include <common/utils.h>
+#include <common/mi-lttng.h>
#include <lttng/snapshot.h>
#include "../command.h"
OPT_LIST_COMMANDS,
};
+static struct mi_writer *writer;
+
static struct poptOption snapshot_opts[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
{"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
return NULL;
}
+static int mi_list_output(void)
+{
+ int ret;
+ struct lttng_snapshot_output *s_iter;
+ struct lttng_snapshot_output_list *list;
+
+ assert(writer);
+
+ ret = lttng_snapshot_list_output(current_session_name, &list);
+ if (ret < 0) {
+ goto error;
+ }
+
+ ret = mi_lttng_snapshot_output_session_name(writer, current_session_name);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ while ((s_iter = lttng_snapshot_output_list_get_next(list)) != NULL) {
+ ret = mi_lttng_snapshot_list_output(writer, s_iter);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+ }
+
+
+ /* Close snapshot snapshots element */
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ /* Close snapshot session element */
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ ret = CMD_ERROR;
+ }
+end:
+ lttng_snapshot_output_list_destroy(list);
+error:
+ return ret;
+}
+
static int list_output(void)
{
int ret, output_seen = 0;
return ret;
}
+/*
+ * Delete output by ID (machine interface version).
+ */
+static int mi_del_output(uint32_t id, const char *name)
+{
+ int ret;
+ struct lttng_snapshot_output *output = NULL;
+
+ assert(writer);
+
+ output = lttng_snapshot_output_create();
+ if (!output) {
+ ret = CMD_FATAL;
+ goto error;
+ }
+
+ if (name) {
+ ret = lttng_snapshot_output_set_name(name, output);
+ } else if (id != UINT32_MAX) {
+ ret = lttng_snapshot_output_set_id(id, output);
+ } else {
+ ret = CMD_ERROR;
+ goto error;
+ }
+ if (ret < 0) {
+ ret = CMD_FATAL;
+ goto error;
+ }
+
+ ret = lttng_snapshot_del_output(current_session_name, output);
+ if (ret < 0) {
+ ret = CMD_FATAL;
+ goto error;
+ }
+
+ ret = mi_lttng_snapshot_del_output(writer, id, name, current_session_name);
+ if (ret) {
+ ret = CMD_ERROR;
+ }
+
+error:
+ lttng_snapshot_output_destroy(output);
+ return ret;
+}
+
/*
* Delete output by ID.
*/
return ret;
}
+/*
+ * Add output from the user URL (machine interface).
+ */
+static int mi_add_output(const char *url)
+{
+ int ret;
+ struct lttng_snapshot_output *output = NULL;
+ char name[NAME_MAX];
+ const char *n_ptr;
+
+ if (!url && (!opt_data_url || !opt_ctrl_url)) {
+ ret = CMD_ERROR;
+ goto error;
+ }
+
+ output = create_output_from_args(url);
+ if (!output) {
+ ret = CMD_FATAL;
+ goto error;
+ }
+
+ /* This call, if successful, populates the id of the output object. */
+ ret = lttng_snapshot_add_output(current_session_name, output);
+ if (ret < 0) {
+ ret = CMD_ERROR;
+ goto error;
+ }
+
+ n_ptr = lttng_snapshot_output_get_name(output);
+ if (*n_ptr == '\0') {
+ int pret;
+ pret = snprintf(name, sizeof(name), DEFAULT_SNAPSHOT_NAME "-%" PRIu32,
+ lttng_snapshot_output_get_id(output));
+ if (pret < 0) {
+ PERROR("snprintf add output name");
+ }
+ n_ptr = name;
+ }
+
+ ret = mi_lttng_snapshot_add_output(writer, current_session_name, n_ptr,
+ output);
+ if (ret) {
+ ret = CMD_ERROR;
+ }
+
+error:
+ lttng_snapshot_output_destroy(output);
+ return ret;
+}
+
/*
* Add output from the user URL.
*/
static int cmd_add_output(int argc, const char **argv)
{
- int ret = CMD_SUCCESS;
+ int ret;
if (argc < 2 && (!opt_data_url || !opt_ctrl_url)) {
usage(stderr);
goto end;
}
- ret = add_output(argv[1]);
+ if (lttng_opt_mi) {
+ ret = mi_add_output(argv[1]);
+ } else {
+ ret = add_output(argv[1]);
+ }
end:
return ret;
static int cmd_del_output(int argc, const char **argv)
{
- int ret = CMD_SUCCESS;
+ int ret;
char *name;
long id;
errno = 0;
id = strtol(argv[1], &name, 10);
if (id == 0 && errno == 0) {
- ret = del_output(UINT32_MAX, name);
+ if (lttng_opt_mi) {
+ ret = mi_del_output(UINT32_MAX, name);
+ } else {
+ ret = del_output(UINT32_MAX, name);
+ }
} else if (errno == 0 && *name == '\0') {
- ret = del_output(id, NULL);
+ if (lttng_opt_mi) {
+ ret = mi_del_output(id, NULL);
+ } else {
+ ret = del_output(id, NULL);
+ }
} else {
ERR("Argument %s not recognized", argv[1]);
ret = -1;
static int cmd_list_output(int argc, const char **argv)
{
- return list_output();
+ int ret;
+
+ if (lttng_opt_mi) {
+ ret = mi_list_output();
+ } else {
+ ret = list_output();
+ }
+
+ return ret;
+}
+
+/*
+ * Do a snapshot record with the URL if one is given (machine interface).
+ */
+static int mi_record(const char *url)
+{
+ int ret;
+ struct lttng_snapshot_output *output = NULL;
+
+ output = create_output_from_args(url);
+ if (!output) {
+ ret = CMD_FATAL;
+ goto error;
+ }
+
+ ret = lttng_snapshot_record(current_session_name, output, 0);
+ if (ret < 0) {
+ ret = CMD_ERROR;
+ goto error;
+ }
+
+ ret = mi_lttng_snapshot_record(writer, current_session_name, url,
+ opt_ctrl_url, opt_data_url);
+ if (ret) {
+ ret = CMD_ERROR;
+ }
+
+error:
+ lttng_snapshot_output_destroy(output);
+ return ret;
}
/*
if (argc == 2) {
/* With a given URL */
- ret = record(argv[1]);
+ if (lttng_opt_mi) {
+ ret = mi_record(argv[1]);
+ } else {
+ ret = record(argv[1]);
+ }
} else {
- ret = record(NULL);
+ if (lttng_opt_mi) {
+ ret = mi_record(NULL);
+ } else {
+ ret = record(NULL);
+ }
}
return ret;
static int handle_command(const char **argv)
{
- int ret, i = 0, argc;
+ int ret = CMD_SUCCESS, i = 0, argc, command_ret = CMD_SUCCESS;
struct cmd_struct *cmd;
if (argv == NULL || (!opt_ctrl_url && opt_data_url) ||
(opt_ctrl_url && !opt_data_url)) {
usage(stderr);
- ret = CMD_ERROR;
+ command_ret = CMD_ERROR;
goto end;
}
while (cmd->func != NULL) {
/* Find command */
if (strcmp(argv[0], cmd->name) == 0) {
- ret = cmd->func(argc, argv);
+ if (lttng_opt_mi) {
+ /* Action element */
+ ret = mi_lttng_writer_open_element(writer,
+ mi_lttng_element_command_action);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ /* Name of the action */
+ ret = mi_lttng_writer_write_element_string(writer,
+ config_element_name, argv[0]);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ /* Open output element */
+ ret = mi_lttng_writer_open_element(writer,
+ mi_lttng_element_command_output);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+ }
+
+ command_ret = cmd->func(argc, argv);
+
+ if (lttng_opt_mi) {
+ /* Close output and action element */
+ ret = mi_lttng_close_multi_element(writer, 2);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+ }
goto end;
}
i++;
cmd = &actions[i];
}
- /* Command not found */
- ret = CMD_UNDEFINED;
+ ret = -CMD_UNDEFINED;
end:
+ /* Overwrite ret if an error occured in cmd->func() */
+ ret = command_ret ? command_ret : ret;
return ret;
}
-
/*
* The 'snapshot <cmd> <options>' first level command
*/
int cmd_snapshot(int argc, const char **argv)
{
- int opt, ret = CMD_SUCCESS;
+ int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
char *session_name = NULL;
static poptContext pc;
pc = poptGetContext(NULL, argc, argv, snapshot_opts, 0);
poptReadDefaultConfig(pc, 0);
- /* TODO: mi support */
+ /* Mi check */
if (lttng_opt_mi) {
- ret = -LTTNG_ERR_MI_NOT_IMPLEMENTED;
- ERR("mi option not supported");
- goto end;
+ writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
+ if (!writer) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ /* Open command element */
+ ret = mi_lttng_writer_command_open(writer,
+ mi_lttng_element_command_snapshot);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ /* Open output element */
+ ret = mi_lttng_writer_open_element(writer,
+ mi_lttng_element_command_output);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
}
while ((opt = poptGetNextOpt(pc)) != -1) {
current_session_name = opt_session_name;
}
- ret = handle_command(poptGetArgs(pc));
- if (ret < 0) {
- switch (-ret) {
+ command_ret = handle_command(poptGetArgs(pc));
+ if (command_ret < 0) {
+ switch (-command_ret) {
case LTTNG_ERR_EPERM:
ERR("The session needs to be set in no output mode (--no-output)");
break;
case LTTNG_ERR_SNAPSHOT_NODATA:
- WARN("%s", lttng_strerror(ret));
+ WARN("%s", lttng_strerror(command_ret));
break;
default:
- ERR("%s", lttng_strerror(ret));
+ ERR("%s", lttng_strerror(command_ret));
break;
}
- goto end;
+ success = 0;
+ }
+
+ if (lttng_opt_mi) {
+ /* Close output element */
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ /* Success ? */
+ ret = mi_lttng_writer_write_element_bool(writer,
+ mi_lttng_element_command_success, success);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ /* Command element close */
+ ret = mi_lttng_writer_command_close(writer);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto end;
+ }
}
end:
+ /* Mi clean-up */
+ if (writer && mi_lttng_writer_destroy(writer)) {
+ /* Preserve original error code */
+ ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
+ }
+
if (!opt_session_name) {
free(session_name);
}
+
+ /* Overwrite ret if an error occured during handle_command */
+ ret = command_ret ? command_ret : ret;
poptFreeContext(pc);
return ret;
}
#include <include/config.h>
#include <common/config/config.h>
+#include <lttng/snapshot-internal.h>
#include "mi-lttng.h"
#include <assert.h>
const char * const mi_lttng_element_command_enable_channels = "enable-channel";
const char * const mi_lttng_element_command_set_session = "set-session";
const char * const mi_lttng_element_command_disable_event = "disable-event";
+const char * const mi_lttng_element_command_disable_channel = "disable-channel";
+const char * const mi_lttng_element_command_action = "snapshot_action";
const char * const mi_lttng_element_command_output = "output";
const char * const mi_lttng_element_command_success = "success";
const char * const mi_lttng_element_version_license = "license";
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_command_snapshot = "snapshot";
+const char * const mi_lttng_element_command_list_snapshot = "list_snapshot";
+const char * const mi_lttng_element_command_del_snapshot = "del_snapshot";
+const char * const mi_lttng_element_command_add_snapshot = "add_snapshot";
+const char * const mi_lttng_element_command_record_snapshot = "record_snapshot";
/* Strings related to pid */
const char * const mi_lttng_element_pids = "pids";
const char * const mi_lttng_element_pid = "pid";
-const char * const mi_lttng_element_pid_id = "id";
/* Strings related to save command */
const char * const mi_lttng_element_save = "save";
const char * const mi_lttng_element_type_string = "STRING";
const char * const mi_lttng_element_nowrite = "nowrite";
const char * const mi_lttng_element_success = "success";
+const char * const mi_lttng_element_id = "id";
+const char * const mi_lttng_element_empty = "";
/* String related to loglevel */
const char * const mi_lttng_loglevel_str_alert = "TRACE_ALERT";
const char * const mi_lttng_element_calibrate = "calibrate";
const char * const mi_lttng_element_calibrate_function = "FUNCTION";
-const char * const mi_lttng_element_empty = "";
+/* String related to a lttng_snapshot_output */
+const char * const mi_lttng_element_snapshots = "snapshots";
+const char * const mi_lttng_element_snapshot_session_name = "session_name";
+const char * const mi_lttng_element_snapshot_n_ptr = "n_ptr";
+const char * const mi_lttng_element_snapshot_data_url = "data_url";
+const char * const mi_lttng_element_snapshot_ctrl_url = "ctrl_url";
+const char * const mi_lttng_element_snapshot_max_size = "max_size";
const char *mi_lttng_loglevel_string(int value)
{
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;
+}
#include <common/config/config.h>
#include <lttng/lttng.h>
+/* Don't want to reference snapshot-internal.h here */
+struct lttng_snapshot_output;
+
/* Instance of a machine interface writer. */
struct mi_writer {
struct config_writer *writer;
/* Strings related to command */
const char * const mi_lttng_element_command;
const char * const mi_lttng_element_command_name;
+const char * const mi_lttng_element_command_action;
const char * const mi_lttng_element_command_version;
const char * const mi_lttng_element_command_enable_event;
const char * const mi_lttng_element_command_list;
const char * const mi_lttng_element_command_enable_channels;
const char * const mi_lttng_element_command_set_session;
const char * const mi_lttng_element_command_disable_event;
+const char * const mi_lttng_element_command_disable_channel;
+const char * const mi_lttng_element_command_snapshot;
+const char * const mi_lttng_element_command_list_snapshot;
+const char * const mi_lttng_element_command_del_snapshot;
+const char * const mi_lttng_element_command_add_snapshot;
+const char * const mi_lttng_element_command_record_snapshot;
const char * const mi_lttng_element_command_output;
const char * const mi_lttng_element_command_success;
const char * const mi_lttng_element_calibrate;
const char * const mi_lttng_element_calibrate_function;
+/* String related to a lttng_snashot */
+const char * const mi_lttng_element_snapshots;
+const char * const mi_lttng_element_snapshot_session_name;
+const char * const mi_lttng_element_snapshot_n_ptr;
+const char * const mi_lttng_element_snapshot_data_url;
+const char * const mi_lttng_element_snapshot_ctrl_url;
+const char * const mi_lttng_element_snapshot_max_size;
+
/* Utility string function */
const char *mi_lttng_loglevel_string(int value);
const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value);
* is_open Define if we close the context element
* This should be used carefully and the client
* need to close the context element.
- * 0-> False
- * 1-> True
* Returns zero if the element's value could be written.
* Negative values indicate an error.
*/
int mi_lttng_perf_counter_context(struct mi_writer *writer,
struct lttng_event_perf_counter_ctx *perf_context);
+/*
+ * Machine interface of the snapshot list_output.
+ * It specifies the session for which we are listing snapshots,
+ * and it opens a snapshots element to list a sequence
+ * of snapshots.
+ *
+ * writer An instance of a machine interface writer.
+ *
+ * session_name: Snapshot output for session "session_name".
+ *
+ * Note: The client has to close the session and the snapshots elements after
+ * having listed every lttng_snapshot_output.
+ *
+ * Returns zero if the element's value could be written.
+ * Negative values indicate an error.
+ */
+int mi_lttng_snapshot_output_session_name(struct mi_writer *writer,
+ const char *session_name);
+
+/*
+ * Machine interface of the snapshot output.
+ * The machine interface serializes the following attributes:
+ * - id: ID of the snapshot output.
+ * - name: Name of the output.
+ * - data_url : Destination of the output.
+ * - ctrl_url: Destination of the output.
+ * - max_size: total size of all stream combined.
+ *
+ * writer An instance of a machine interface writer.
+ *
+ * output: A list of snapshot_output.
+ *
+ * Returns zero if the element's value could be written.
+ * Negative values indicate an error.
+ */
+int mi_lttng_snapshot_list_output(struct mi_writer *writer,
+ struct lttng_snapshot_output *output);
+
+/*
+ * Machine interface of the output of the command snapshot del output
+ * when deleting a snapshot either by id or by name.
+ * If the snapshot was found and successfully deleted using its id,
+ * it return the id of the snapshot and the current session name on which it
+ * was attached.
+ *
+ * Otherwise, it do the same process with the name of the snapshot, if the
+ * snapshot output id is undefined.
+ *
+ * writer An instance of a machine interface writer.
+ *
+ * id: ID of the snapshot output.
+ *
+ * name: Name of the snapshot.
+ *
+ * current_session_name: Session to which the snapshot belongs.
+ *
+ * Returns zero if the element's value could be written.
+ * Negative values indicate an error.
+ */
+int mi_lttng_snapshot_del_output(struct mi_writer *writer, int id,
+ const char *name, const char *current_session_name);
+
+/*
+ * Machine interface of the output of the command snapshot add output
+ * when adding a snapshot from a user URL.
+ *
+ * If the snapshot was successfully added, the machine interface lists
+ * these information:
+ * - id: ID of the newly add snapshot output.
+ * - current_session_name: Name of the session to which the output was added.
+ * - ctrl_url: Destination of the output.
+ * - max_size: total size of all stream combined.
+ *
+ * writer An instance of a machine interface writer.
+ *
+ * current_session_name: Session to which the snapshot belongs.
+ *
+ * n_ptr:
+ *
+ * output: iterator over a lttng_snapshot_output_list which contain
+ * the snapshot output informations.
+ *
+ * Returns zero if the element's value could be written.
+ * Negative values indicate an error.
+ */
+int mi_lttng_snapshot_add_output(struct mi_writer *writer,
+ const char *current_session_name, const char *n_ptr,
+ struct lttng_snapshot_output *output);
+
+/*
+ * Machine interface of the output of the command snapshot
+ * record from a URL (if given).
+ *
+ * If the snapshot is successfully recorded from a url, the machine interface
+ * output the following information:
+ * - url: Destination of the output stored in the snapshot.
+ *
+ * Otherwise, the machine interface output the data and ctrl url received
+ * from the command-line.
+ *
+ * writer An instance of a machine interface writer.
+ *
+ * current_session_name: Snapshot record for session "current_session_name".
+ *
+ * ctrl_url, data_url: Destination of the output receive from the command-line.
+ *
+ * Returns zero if the element's value could be written.
+ * Negative values indicate an error.
+ */
+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);
+
#endif /* _MI_LTTNG_H */
</xs:all>
</xs:complexType>
+ <!-- Maps to struct lttng_snapshot_output -->
+ <xs:complexType name="snapshot_type">
+ <xs:all>
+ <xs:element name="id" type="uint32_type" minOccurs="0" />
+ <xs:element name="max_size" type="uint64_type" minOccurs="0" />
+ <xs:element name="name" type="name_type" minOccurs="0" />
+ <xs:element name="session_name" type="name_type" minOccurs="0" />
+ <xs:element name="ctrl_url" type="name_type" minOccurs="0"/>
+ <xs:element name="data_url" type="name_type" minOccurs="0"/>
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="snapshots_type">
+ <xs:sequence>
+ <xs:element name="snapshot" type="snapshot_type" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
<xs:complexType name="channels_type">
<xs:sequence>
<xs:element name="channel" type="channel_type" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="live_timer_interval" type="uint32_type" minOccurs="0" />
<xs:element name="channels" type="channels_type" minOccurs="0" />
<xs:element name="domains" type="domains_type" minOccurs="0" />
+ <xs:element name="snapshots" type="snapshots_type" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:sequence>
</xs:complexType>
+ <xs:complexType name="snapshot_action_type">
+ <xs:sequence>
+ <xs:element name="name" type="snapshot_actiontype_type" minOccurs="0" />
+ <xs:element name="output" type="output_type" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Type of snapshot commands -->
+ <xs:simpleType name="snapshot_actiontype_type">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="list-output"/>
+ <xs:enumeration value="del-output"/>
+ <xs:enumeration value="add-output"/>
+ <xs:enumeration value="record-output"/>
+ </xs:restriction>
+ </xs:simpleType>
+
<xs:complexType name="output_type">
<xs:choice>
<xs:element name="domains" type="domains_type" minOccurs="0" />
+ <xs:element name="session" type="session_type" minOccurs="0" />
<xs:element name="sessions" type="sessions_type" minOccurs="0" />
<xs:element name="session" type="session_type" minOccurs="0" />
+ <xs:element name="snapshot_action" type="snapshot_action_type" minOccurs="0" />
<xs:element name="version" type="version_type" minOccurs="0" />
<xs:element name="save" type="save_type" minOccurs="0" />
<xs:element name="load" type="load_type" minOccurs="0" />
<xs:element name="channels" type="channels_type" minOccurs="0" />
<xs:element name="events" type="event_list_type" minOccurs="0" />
<xs:element name="channel" type="channel_type" minOccurs="0" />
+ <xs:element name="channels" type="channels_type" minOccurs="0" />
</xs:choice>
</xs:complexType>
<xs:restriction base="xs:string">
<xs:enumeration value="create" />
<xs:enumeration value="list" />
+ <xs:enumeration value="snapshot" />
<xs:enumeration value="version" />
<xs:enumeration value="save" />
<xs:enumeration value="load" />
<xs:enumeration value="enable-event" />
<xs:enumeration value="set-session" />
<xs:enumeration value="disable-event" />
+ <xs:enumeration value="disable-channel" />
</xs:restriction>
</xs:simpleType>