/* * Set URL for a consumer for a session and domain. * * Return 0 on success, else a negative value. */ int lttng_set_consumer_url(struct lttng_handle *handle, const char *control_url, const char *data_url) { int ret; ssize_t size; struct lttcomm_session_msg lsm; struct lttng_uri *uris = NULL; if (handle == NULL || (control_url == NULL && data_url == NULL)) { return -LTTNG_ERR_INVALID; } memset(&lsm, 0, sizeof(lsm)); lsm.cmd_type = LTTNG_SET_CONSUMER_URI; lttng_ctl_copy_string(lsm.session.name, handle->session_name, sizeof(lsm.session.name)); lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain); size = uri_parse_str_urls(control_url, data_url, &uris); if (size < 0) { return -LTTNG_ERR_INVALID; } lsm.u.uri.size = size; ret = lttng_ctl_ask_sessiond_varlen(&lsm, uris, sizeof(struct lttng_uri) * size, NULL); free(uris); return ret; }
/* * Create a session exclusively used for snapshot. * * Returns LTTNG_OK on success or a negative error code. */ int lttng_create_session_snapshot(const char *name, const char *snapshot_url) { int ret; ssize_t size; struct lttcomm_session_msg lsm; struct lttng_uri *uris = NULL; if (name == NULL) { return -LTTNG_ERR_INVALID; } memset(&lsm, 0, sizeof(lsm)); lsm.cmd_type = LTTNG_CREATE_SESSION_SNAPSHOT; lttng_ctl_copy_string(lsm.session.name, name, sizeof(lsm.session.name)); size = uri_parse_str_urls(snapshot_url, NULL, &uris); if (size < 0) { return -LTTNG_ERR_INVALID; } lsm.u.uri.size = size; ret = lttng_ctl_ask_sessiond_varlen(&lsm, uris, sizeof(struct lttng_uri) * size, NULL); free(uris); return ret; }
/* * This is an extension of create session that is ONLY and SHOULD only be used * by the lttng command line program. It exists to avoid using URI parsing in * the lttng client. * * We need the date and time for the trace path subdirectory for the case where * the user does NOT define one using either -o or -U. Using the normal * lttng_create_session API call, we have no clue on the session daemon side if * the URL was generated automatically by the client or define by the user. * * So this function "wrapper" is hidden from the public API, takes the datetime * string and appends it if necessary to the URI subdirectory before sending it * to the session daemon. * * With this extra function, the lttng_create_session call behavior is not * changed and the timestamp is appended to the URI on the session daemon side * if necessary. */ int _lttng_create_session_ext(const char *name, const char *url, const char *datetime) { int ret; ssize_t size; struct lttcomm_session_msg lsm; struct lttng_uri *uris = NULL; if (name == NULL || datetime == NULL) { return -LTTNG_ERR_INVALID; } memset(&lsm, 0, sizeof(lsm)); lsm.cmd_type = LTTNG_CREATE_SESSION; lttng_ctl_copy_string(lsm.session.name, name, sizeof(lsm.session.name)); /* There should never be a data URL */ size = uri_parse_str_urls(url, NULL, &uris); if (size < 0) { ret = -LTTNG_ERR_INVALID; goto error; } lsm.u.uri.size = size; if (size > 0 && uris[0].dtype != LTTNG_DST_PATH && strlen(uris[0].subdir) == 0) { /* Don't append datetime if the name was automatically created. */ if (strncmp(name, DEFAULT_SESSION_NAME "-", strlen(DEFAULT_SESSION_NAME) + 1)) { ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s-%s", name, datetime); } else { ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s", name); } if (ret < 0) { PERROR("snprintf uri subdir"); ret = -LTTNG_ERR_FATAL; goto error; } } ret = lttng_ctl_ask_sessiond_varlen(&lsm, uris, sizeof(struct lttng_uri) * size, NULL); error: free(uris); return ret; }
static int network_location_set_from_uri_strings( struct lttng_session_descriptor_network_location *location, const char *control, const char *data) { int ret = 0; ssize_t uri_count; struct lttng_uri *parsed_uris = NULL; struct lttng_uri *control_uri = NULL; struct lttng_uri *data_uri = NULL; uri_count = uri_parse_str_urls(control, data, &parsed_uris); if (uri_count != 2 && uri_count != 0) { ret = -1; goto end; } /* * uri_parse_str_urls returns a contiguous array of lttng_uris whereas * session descriptors expect individually allocated lttng_uris. */ if (uri_count == 2) { control_uri = zmalloc(sizeof(*control_uri)); data_uri = zmalloc(sizeof(*data_uri)); if (!control_uri || !data_uri) { ret = -1; goto end; } memcpy(control_uri, &parsed_uris[0], sizeof(*control_uri)); memcpy(data_uri, &parsed_uris[1], sizeof(*data_uri)); } /* Ownership of control and data uris is transferred. */ ret = network_location_set_from_lttng_uris( location, control_uri, data_uri); control_uri = NULL; data_uri = NULL; end: free(parsed_uris); free(control_uri); free(data_uri); return ret; }
/* * Create a session exclusively used for live. * * Returns LTTNG_OK on success or a negative error code. */ int lttng_create_session_live(const char *name, const char *url, unsigned int timer_interval) { int ret; ssize_t size; struct lttcomm_session_msg lsm; struct lttng_uri *uris = NULL; if (name == NULL || timer_interval == 0) { return -LTTNG_ERR_INVALID; } memset(&lsm, 0, sizeof(lsm)); lsm.cmd_type = LTTNG_CREATE_SESSION_LIVE; lttng_ctl_copy_string(lsm.session.name, name, sizeof(lsm.session.name)); if (url) { size = uri_parse_str_urls(url, NULL, &uris); if (size <= 0) { ret = -LTTNG_ERR_INVALID; goto end; } /* file:// is not accepted for live session. */ if (uris[0].dtype == LTTNG_DST_PATH) { ret = -LTTNG_ERR_INVALID; goto end; } } else { size = 0; } lsm.u.session_live.nb_uri = size; lsm.u.session_live.timer_interval = timer_interval; ret = lttng_ctl_ask_sessiond_varlen(&lsm, uris, sizeof(struct lttng_uri) * size, NULL); end: free(uris); return ret; }
int lttng_save_session_attr_set_output_url( struct lttng_save_session_attr *attr, const char *url) { int ret = 0; size_t len; ssize_t size; struct lttng_uri *uris = NULL; if (!attr) { ret = -LTTNG_ERR_INVALID; goto error; } if (!url) { attr->configuration_url[0] = '\0'; ret = 0; goto end; } len = strlen(url); if (len >= PATH_MAX) { ret = -LTTNG_ERR_INVALID; goto error; } size = uri_parse_str_urls(url, NULL, &uris); if (size <= 0 || uris[0].dtype != LTTNG_DST_PATH) { ret = -LTTNG_ERR_INVALID; goto error; } /* Copy string plus the NULL terminated byte. */ lttng_ctl_copy_string(attr->configuration_url, uris[0].dst.path, sizeof(attr->configuration_url)); end: error: free(uris); return ret; }
static struct lttng_session_descriptor *create_session_descriptor(void) { int ret; ssize_t uri_count; enum output_type output_type; struct lttng_uri *uris = NULL; struct lttng_session_descriptor *descriptor = NULL; const char *uri_str1 = NULL, *uri_str2 = NULL; char local_output_path[LTTNG_PATH_MAX] = {}; if (opt_no_output) { output_type = OUTPUT_NONE; } else if (opt_output_path) { char *expanded_output_path; output_type = OUTPUT_LOCAL; expanded_output_path = utils_expand_path(opt_output_path); if (!expanded_output_path) { ERR("Failed to expand output path."); goto end; } ret = lttng_strncpy(local_output_path, expanded_output_path, sizeof(local_output_path)); free(expanded_output_path); if (ret) { ERR("Output path exceeds the maximal supported length (%zu bytes)", sizeof(local_output_path)); goto end; } } else if (opt_url || opt_ctrl_url) { uri_str1 = opt_ctrl_url ? opt_ctrl_url : opt_url; uri_str2 = opt_data_url; uri_count = uri_parse_str_urls(uri_str1, uri_str2, &uris); if (uri_count != 1 && uri_count != 2) { ERR("Unrecognized URL format."); goto end; } switch (uri_count) { case 1: output_type = OUTPUT_LOCAL; if (uris[0].dtype != LTTNG_DST_PATH) { ERR("Unrecognized URL format."); goto end; } ret = lttng_strncpy(local_output_path, uris[0].dst.path, sizeof(local_output_path)); if (ret) { ERR("Output path exceeds the maximal supported length (%zu bytes)", sizeof(local_output_path)); } break; case 2: output_type = OUTPUT_NETWORK; break; default: /* Already checked. */ abort(); } } else { output_type = OUTPUT_UNSPECIFIED; } if (opt_snapshot) { /* Snapshot session. */ switch (output_type) { case OUTPUT_UNSPECIFIED: case OUTPUT_LOCAL: descriptor = lttng_session_descriptor_snapshot_local_create( opt_session_name, output_type == OUTPUT_LOCAL ? local_output_path : NULL); break; case OUTPUT_NONE: descriptor = lttng_session_descriptor_snapshot_create( opt_session_name); break; case OUTPUT_NETWORK: descriptor = lttng_session_descriptor_snapshot_network_create( opt_session_name, uri_str1, uri_str2); break; default: abort(); } } else if (opt_live_timer) { /* Live session. */ if (output_type != OUTPUT_UNSPECIFIED && output_type != OUTPUT_NETWORK) { ERR("Unsupported output type specified for live session."); goto end; } descriptor = lttng_session_descriptor_live_network_create( opt_session_name, uri_str1, uri_str2, opt_live_timer); } else { /* Regular session. */ switch (output_type) { case OUTPUT_UNSPECIFIED: case OUTPUT_LOCAL: descriptor = lttng_session_descriptor_local_create( opt_session_name, output_type == OUTPUT_LOCAL ? local_output_path : NULL); break; case OUTPUT_NONE: descriptor = lttng_session_descriptor_create( opt_session_name); break; case OUTPUT_NETWORK: descriptor = lttng_session_descriptor_network_create( opt_session_name, uri_str1, uri_str2); break; default: abort(); } } if (!descriptor) { ERR("Failed to initialize session creation command."); } else { /* * Auto-launch the relay daemon when a live session * is created using default URLs. */ if (!opt_url && !opt_ctrl_url && !opt_data_url && opt_live_timer && !check_relayd()) { int ret; const char *pathname = opt_relayd_path ? : INSTALL_BIN_PATH "/lttng-relayd"; ret = spawn_relayd(pathname, 0); if (ret < 0) { lttng_session_descriptor_destroy(descriptor); descriptor = NULL; } } }
LTTNG_HIDDEN enum lttng_error_code lttng_session_descriptor_set_default_output( struct lttng_session_descriptor *descriptor, time_t *session_creation_time, const char *absolute_home_path) { enum lttng_error_code ret_code = LTTNG_OK; struct lttng_uri *uris = NULL; switch (descriptor->output_type) { case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE: goto end; case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL: { int ret; ssize_t uri_ret; char local_uri[LTTNG_PATH_MAX]; char creation_datetime_suffix[17] = {}; if (session_creation_time) { size_t strftime_ret; struct tm *timeinfo; timeinfo = localtime(session_creation_time); if (!timeinfo) { ret_code = LTTNG_ERR_FATAL; goto end; } strftime_ret = strftime(creation_datetime_suffix, sizeof(creation_datetime_suffix), "-%Y%m%d-%H%M%S", timeinfo); if (strftime_ret == 0) { ERR("Failed to format session creation timestamp while setting default local output destination"); ret_code = LTTNG_ERR_FATAL; goto end; } } assert(descriptor->name); ret = snprintf(local_uri, sizeof(local_uri), "file://%s/%s/%s%s", absolute_home_path, DEFAULT_TRACE_DIR_NAME, descriptor->name, creation_datetime_suffix); if (ret >= sizeof(local_uri)) { ERR("Truncation occurred while setting default local output destination"); ret_code = LTTNG_ERR_SET_URL; goto end; } else if (ret < 0) { PERROR("Failed to format default local output URI"); ret_code = LTTNG_ERR_SET_URL; goto end; } uri_ret = uri_parse(local_uri, &uris); if (uri_ret != 1) { ret_code = LTTNG_ERR_SET_URL; goto end; } free(descriptor->output.local); descriptor->output.local = &uris[0]; uris = NULL; break; } case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK: { int ret; ssize_t uri_ret; struct lttng_uri *control = NULL, *data = NULL; uri_ret = uri_parse_str_urls("net://127.0.0.1", NULL, &uris); if (uri_ret != 2) { ret_code = LTTNG_ERR_SET_URL; goto end; } control = uri_copy(&uris[0]); data = uri_copy(&uris[1]); if (!control || !data) { free(control); free(data); ret_code = LTTNG_ERR_SET_URL; goto end; } /* Ownership of uris is transferred. */ ret = network_location_set_from_lttng_uris( &descriptor->output.network, control, data); if (ret) { abort(); ret_code = LTTNG_ERR_SET_URL; goto end; } break; } default: abort(); } end: free(uris); return ret_code; }