+ int ret, i;
+ char shm_path[LTTNG_PATH_MAX] = {};
+ struct lttng_session_descriptor *session_descriptor = NULL;
+ enum lttng_session_descriptor_status descriptor_status;
+ enum lttng_error_code ret_code;
+ struct lttng_session *sessions = NULL;
+ const struct lttng_session *created_session = NULL;
+ const char *created_session_name;
+
+ /* Validate options. */
+ if (opt_session_name) {
+ if (strlen(opt_session_name) > NAME_MAX) {
+ ERR("Session name too long. Length must be lower or equal to %d",
+ NAME_MAX);
+ ret = CMD_ERROR;
+ goto error;
+ }
+ /*
+ * Check if the session name begins with "auto-" or is exactly "auto".
+ * Both are reserved for the default session name. See bug #449 to
+ * understand why we need to check both here.
+ */
+ if ((strncmp(opt_session_name, DEFAULT_SESSION_NAME "-",
+ strlen(DEFAULT_SESSION_NAME) + 1) == 0) ||
+ (strncmp(opt_session_name, DEFAULT_SESSION_NAME,
+ strlen(DEFAULT_SESSION_NAME)) == 0 &&
+ strlen(opt_session_name) == strlen(DEFAULT_SESSION_NAME))) {
+ ERR("%s is a reserved keyword for default session(s)",
+ DEFAULT_SESSION_NAME);
+ ret = CMD_ERROR;
+ goto error;
+ }
+ }
+
+ if (opt_snapshot && opt_live_timer) {
+ ERR("Snapshot and live modes are mutually exclusive.");
+ ret = CMD_ERROR;
+ goto error;
+ }
+
+ if ((!opt_ctrl_url && opt_data_url) || (opt_ctrl_url && !opt_data_url)) {
+ ERR("Both control and data URLs must be specified.");
+ ret = CMD_ERROR;
+ goto error;
+ }
+
+ session_descriptor = create_session_descriptor();
+ if (!session_descriptor) {
+ ret = CMD_ERROR;
+ goto error;
+ }
+ ret_code = lttng_create_session_ext(session_descriptor);
+ if (ret_code != LTTNG_OK) {
+ ERR("%s", lttng_strerror(-ret_code));
+ ret = CMD_ERROR;
+ goto error;
+ }
+
+ descriptor_status = lttng_session_descriptor_get_session_name(
+ session_descriptor, &created_session_name);
+ if (descriptor_status != LTTNG_SESSION_DESCRIPTOR_STATUS_OK) {
+ ERR("Failed to obtain created session name");
+ ret = CMD_ERROR;
+ goto error;
+ }
+
+ ret = lttng_list_sessions(&sessions);
+ if (ret < 0) {
+ ERR("Failed to fetch properties of created session: %s",
+ lttng_strerror(ret));
+ ret = CMD_ERROR;
+ goto error;
+ }
+ for (i = 0; i < ret; i++) {
+ if (!strcmp(created_session_name, sessions[i].name)) {
+ created_session = &sessions[i];
+ break;
+ }
+ }
+ if (!created_session) {
+ ERR("Failed to fetch properties of created session");
+ ret = CMD_ERROR;
+ goto error;
+ }
+
+ if (opt_shm_path) {
+ char datetime_suffix[17] = {};
+
+ /*
+ * An auto-generated session name already includes the creation
+ * timestamp.
+ */
+ if (opt_session_name) {
+ uint64_t creation_time;
+ struct tm *timeinfo;
+ time_t creation_time_t;
+ size_t strftime_ret;
+
+ ret_code = lttng_session_get_creation_time(
+ created_session,
+ &creation_time);
+ if (ret_code != LTTNG_OK) {
+ ERR("%s", lttng_strerror(-ret_code));
+ ret = CMD_ERROR;
+ goto error;
+ }
+ creation_time_t = (time_t) creation_time;
+ timeinfo = localtime(&creation_time_t);
+ if (!timeinfo) {
+ PERROR("Failed to interpret session creation time");
+ ret = CMD_ERROR;
+ goto error;
+ }
+ strftime_ret = strftime(datetime_suffix,
+ sizeof(datetime_suffix),
+ "-%Y%m%d-%H%M%S", timeinfo);
+ if (strftime_ret == 0) {
+ ERR("Failed to format session creation time.");
+ ret = CMD_ERROR;
+ goto error;
+ }
+ }
+
+ ret = snprintf(shm_path, sizeof(shm_path),
+ "%s/%s%s", opt_shm_path, created_session_name,
+ datetime_suffix);
+ if (ret < 0 || ret >= sizeof(shm_path)) {
+ ERR("Failed to format the shared memory path.");
+ ret = CMD_ERROR;
+ goto error;
+ }
+ ret = lttng_set_session_shm_path(created_session_name,
+ shm_path);