+ size = uri_parse_str_urls(snapshot_url, NULL, &uris);
+ if (size < 0) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+ /*
+ * If the user does not specify a custom subdir, use the session name.
+ */
+ if (size > 0 && uris[0].dtype != LTTNG_DST_PATH &&
+ strlen(uris[0].subdir) == 0) {
+ ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s",
+ name);
+ if (ret < 0) {
+ PERROR("Failed to set session name as network destination sub-directory");
+ ret = -LTTNG_ERR_FATAL;
+ goto end;
+ } else if (ret >= sizeof(uris[0].subdir)) {
+ /* Truncated output. */
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+ }
+
+ switch (size) {
+ case 0:
+ descriptor = lttng_session_descriptor_snapshot_create(name);
+ break;
+ case 1:
+ if (uris[0].dtype != LTTNG_DST_PATH) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+ descriptor = lttng_session_descriptor_snapshot_local_create(
+ name,
+ uris[0].dst.path);
+ break;
+ case 2:
+ descriptor = lttng_session_descriptor_snapshot_network_create(
+ name,
+ snapshot_url,
+ NULL);
+ break;
+ default:
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+ if (!descriptor) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = lttng_create_session_ext(descriptor);
+ ret = ret_code == LTTNG_OK ? 0 : -ret_code;
+end:
+ lttng_session_descriptor_destroy(descriptor);
+ free(uris);
+ 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;
+ enum lttng_error_code ret_code;
+ struct lttng_session_descriptor *descriptor = NULL;
+
+ if (!name) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ if (url) {
+ descriptor = lttng_session_descriptor_live_network_create(
+ name, url, NULL, timer_interval);
+ } else {
+ descriptor = lttng_session_descriptor_live_create(
+ name, timer_interval);
+ }
+ if (!descriptor) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = lttng_create_session_ext(descriptor);
+ ret = ret_code == LTTNG_OK ? 0 : -ret_code;
+end:
+ lttng_session_descriptor_destroy(descriptor);
+ return ret;
+}
+
+/*
+ * Destroy session using name.
+ * Returns size of returned session payload data or a negative error code.
+ */
+static
+int _lttng_destroy_session(const char *session_name)
+{
+ struct lttcomm_session_msg lsm;
+
+ if (session_name == NULL) {
+ return -LTTNG_ERR_INVALID;
+ }
+
+ memset(&lsm, 0, sizeof(lsm));
+ lsm.cmd_type = LTTNG_DESTROY_SESSION;
+
+ lttng_ctl_copy_string(lsm.session.name, session_name,
+ sizeof(lsm.session.name));
+
+ return lttng_ctl_ask_sessiond(&lsm, NULL);