+ fprintf(ofp, " proto://[HOST|IP][:PORT1[:PORT2]][/TRACE_PATH]\n");
+ fprintf(ofp, "\n");
+ fprintf(ofp, " Supported protocols are (proto):\n");
+ fprintf(ofp, " > file://...\n");
+ fprintf(ofp, " Local filesystem full path.\n");
+ fprintf(ofp, "\n");
+ fprintf(ofp, " > net[6]://...\n");
+ fprintf(ofp, " This will use the default network transport layer which is\n");
+ fprintf(ofp, " TCP for both control (PORT1) and data port (PORT2).\n");
+ fprintf(ofp, " The default ports are respectively 5342 and 5343.\n");
+ fprintf(ofp, "\n");
+ fprintf(ofp, " > tcp[6]://...\n");
+ fprintf(ofp, " Can only be used with -C and -D together\n");
+ fprintf(ofp, "\n");
+ fprintf(ofp, "NOTE: IPv6 address MUST be enclosed in brackets '[]' (rfc2732)\n");
+ fprintf(ofp, "\n");
+ fprintf(ofp, "Examples:\n");
+ fprintf(ofp, " # lttng create -U net://192.168.1.42\n");
+ fprintf(ofp, " Uses TCP and default ports for the given destination.\n");
+ fprintf(ofp, " # lttng create -U net6://[fe80::f66d:4ff:fe53:d220]\n");
+ fprintf(ofp, " Uses TCP, default ports and IPv6.\n");
+ fprintf(ofp, " # lttng create s1 -U net://myhost.com:3229\n");
+ fprintf(ofp, " Set the consumer to the remote HOST on port 3229 for control.\n");
+ fprintf(ofp, "\n");
+}
+
+/*
+ * Retrieve the created session and
+ * mi output it of the created session based on provided argument
+ * This is currently a summary of what was pretty printed and is subject to
+ * enhancements.
+ * str_url is a placement string for output url (snapshot or regular trace)
+ */
+static int mi_created_session(const char *session_name)
+{
+ int ret, i, count, found;
+ struct lttng_session *sessions;
+
+ /* session_name should not be null */
+ assert(session_name);
+ assert(writer);
+
+ count = lttng_list_sessions(&sessions);
+ if (count < 0) {
+ ret = count;
+ ERR("%s", lttng_strerror(ret));
+ goto error;
+ }
+
+ if (count == 0) {
+ ERR("Error session creation failed: session %s not found", session_name);
+ ret = -LTTNG_ERR_SESS_NOT_FOUND;
+ goto end;
+ }
+
+ found = 0;
+ for (i = 0; i < count; i++) {
+ if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) {
+ found = 1;
+ ret = mi_lttng_session(writer, &sessions[i], 0);
+ if (ret) {
+ goto error;
+ }
+ break;
+ }
+ }
+
+ if (!found) {
+ ret = -LTTNG_ERR_SESS_NOT_FOUND;
+ } else {
+ ret = CMD_SUCCESS;
+ }
+
+error:
+ free(sessions);
+end:
+ return ret;
+}
+
+/*
+ * For a session name, set the consumer URLs.
+ */
+static int set_consumer_url(const char *session_name, const char *ctrl_url,
+ const char *data_url)
+{
+ int ret;
+ struct lttng_handle *handle;
+ struct lttng_domain dom;
+
+ assert(session_name);
+
+ /*
+ * Set handle with the session name and the domain set to 0. This means to
+ * the session daemon that the next action applies on the tracing session
+ * rather then the domain specific session.
+ */
+ memset(&dom, 0, sizeof(dom));
+
+ handle = lttng_create_handle(session_name, &dom);
+ if (handle == NULL) {
+ ret = CMD_FATAL;
+ goto error;
+ }
+
+ ret = lttng_set_consumer_url(handle, ctrl_url, data_url);
+ if (ret < 0) {
+ goto error;
+ }
+
+ if (ctrl_url) {
+ MSG("Control URL %s set for session %s", ctrl_url, session_name);
+ }
+
+ if (data_url) {
+ MSG("Data URL %s set for session %s", data_url, session_name);
+ }
+
+error:
+ lttng_destroy_handle(handle);
+ return ret;
+}
+
+static int add_snapshot_output(const char *session_name, const char *ctrl_url,
+ const char *data_url)
+{
+ int ret;
+ struct lttng_snapshot_output *output = NULL;
+
+ assert(session_name);
+
+ output = lttng_snapshot_output_create();
+ if (!output) {
+ ret = CMD_FATAL;
+ goto error_create;
+ }
+
+ if (ctrl_url) {
+ ret = lttng_snapshot_output_set_ctrl_url(ctrl_url, output);
+ if (ret < 0) {
+ goto error;
+ }
+ }
+
+ if (data_url) {
+ ret = lttng_snapshot_output_set_data_url(data_url, output);
+ if (ret < 0) {
+ goto error;
+ }
+ }
+
+ /* This call, if successful, populates the id of the output object. */
+ ret = lttng_snapshot_add_output(session_name, output);
+ if (ret < 0) {
+ goto error;
+ }
+
+error:
+ lttng_snapshot_output_destroy(output);
+error_create:
+ return ret;