X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=bd63389ee94b510986c545644017607a35106152;hp=ba963ffc53c5e15f44ac756ce2842f9767d27ff5;hb=eded6438f3b15eccc391525f653e03293a890d32;hpb=a905c62444dc13fa4547d3b86d5d0f3293fa7021 diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index ba963ffc5..bd63389ee 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -187,6 +187,11 @@ static int get_ust_runtime_stats(struct ltt_session *session, int ret; struct ltt_ust_session *usess; + if (!discarded_events || !lost_packets) { + ret = -1; + goto end; + } + usess = session->ust_session; assert(discarded_events); assert(lost_packets); @@ -270,9 +275,12 @@ static void list_lttng_channels(enum lttng_domain_type domain, rcu_read_lock(); cds_lfht_for_each_entry(session->ust_session->domain_global.channels->ht, &iter.iter, uchan, node.node) { - uint64_t discarded_events, lost_packets; + uint64_t discarded_events = 0, lost_packets = 0; - strncpy(channels[i].name, uchan->name, LTTNG_SYMBOL_NAME_LEN); + if (lttng_strncpy(channels[i].name, uchan->name, + LTTNG_SYMBOL_NAME_LEN)) { + break; + } channels[i].attr.overwrite = uchan->attr.overwrite; channels[i].attr.subbuf_size = uchan->attr.subbuf_size; channels[i].attr.num_subbuf = uchan->attr.num_subbuf; @@ -753,12 +761,15 @@ static int add_uri_to_consumer(struct consumer_output *consumer, DBG2("Setting trace directory path from URI to %s", uri->dst.path); memset(consumer->dst.trace_path, 0, sizeof(consumer->dst.trace_path)); - strncpy(consumer->dst.trace_path, uri->dst.path, - sizeof(consumer->dst.trace_path)); + /* Explicit length checks for strcpy and strcat. */ + if (strlen(uri->dst.path) + strlen(default_trace_dir) + >= sizeof(consumer->dst.trace_path)) { + ret = LTTNG_ERR_FATAL; + goto error; + } + strcpy(consumer->dst.trace_path, uri->dst.path); /* Append default trace dir */ - strncat(consumer->dst.trace_path, default_trace_dir, - sizeof(consumer->dst.trace_path) - - strlen(consumer->dst.trace_path) - 1); + strcat(consumer->dst.trace_path, default_trace_dir); /* Flag consumer as local. */ consumer->type = CONSUMER_DST_LOCAL; break; @@ -1322,16 +1333,6 @@ int cmd_enable_channel(struct ltt_session *session, attr->attr.switch_timer_interval = 0; } - /* - * The ringbuffer (both in user space and kernel) behave badly in overwrite - * mode and with less than 2 subbuf so block it right away and send back an - * invalid attribute error. - */ - if (attr->attr.overwrite && attr->attr.num_subbuf < 2) { - ret = LTTNG_ERR_INVALID; - goto error; - } - switch (domain->type) { case LTTNG_DOMAIN_KERNEL: { @@ -1805,7 +1806,7 @@ static int _cmd_enable_event(struct ltt_session *session, int wpipe, bool internal_event) { int ret, channel_created = 0; - struct lttng_channel *attr; + struct lttng_channel *attr = NULL; assert(session); assert(event); @@ -1848,15 +1849,16 @@ static int _cmd_enable_event(struct ltt_session *session, ret = LTTNG_ERR_FATAL; goto error; } - strncpy(attr->name, channel_name, sizeof(attr->name)); + if (lttng_strncpy(attr->name, channel_name, + sizeof(attr->name))) { + ret = LTTNG_ERR_INVALID; + goto error; + } ret = cmd_enable_channel(session, domain, attr, wpipe); if (ret != LTTNG_OK) { - free(attr); goto error; } - free(attr); - channel_created = 1; } @@ -1985,14 +1987,16 @@ static int _cmd_enable_event(struct ltt_session *session, ret = LTTNG_ERR_FATAL; goto error; } - strncpy(attr->name, channel_name, sizeof(attr->name)); + if (lttng_strncpy(attr->name, channel_name, + sizeof(attr->name))) { + ret = LTTNG_ERR_INVALID; + goto error; + } ret = cmd_enable_channel(session, domain, attr, wpipe); if (ret != LTTNG_OK) { - free(attr); goto error; } - free(attr); /* Get the newly created channel reference back */ uchan = trace_ust_find_channel_by_name( @@ -2167,6 +2171,7 @@ error: free(filter_expression); free(filter); free(exclusion); + free(attr); rcu_read_unlock(); return ret; } @@ -2432,7 +2437,15 @@ int cmd_stop_trace(struct ltt_session *session) if (ksession && ksession->active) { DBG("Stop kernel tracing"); - /* Flush metadata if exist */ + ret = kernel_stop_session(ksession); + if (ret < 0) { + ret = LTTNG_ERR_KERN_STOP_FAIL; + goto error; + } + + kernel_wait_quiescent(kernel_tracer_fd); + + /* Flush metadata after stopping (if exists) */ if (ksession->metadata_stream_fd >= 0) { ret = kernel_metadata_flush_buffer(ksession->metadata_stream_fd); if (ret < 0) { @@ -2440,7 +2453,7 @@ int cmd_stop_trace(struct ltt_session *session) } } - /* Flush all buffers before stopping */ + /* Flush all buffers after stopping */ cds_list_for_each_entry(kchan, &ksession->channel_list.head, list) { ret = kernel_flush_buffer(kchan); if (ret < 0) { @@ -2448,14 +2461,6 @@ int cmd_stop_trace(struct ltt_session *session) } } - ret = kernel_stop_session(ksession); - if (ret < 0) { - ret = LTTNG_ERR_KERN_STOP_FAIL; - goto error; - } - - kernel_wait_quiescent(kernel_tracer_fd); - ksession->active = 0; } @@ -3344,10 +3349,18 @@ ssize_t cmd_snapshot_list_outputs(struct ltt_session *session, assert(output->consumer); list[idx].id = output->id; list[idx].max_size = output->max_size; - strncpy(list[idx].name, output->name, sizeof(list[idx].name)); + if (lttng_strncpy(list[idx].name, output->name, + sizeof(list[idx].name))) { + ret = -LTTNG_ERR_INVALID; + goto error; + } if (output->consumer->type == CONSUMER_DST_LOCAL) { - strncpy(list[idx].ctrl_url, output->consumer->dst.trace_path, - sizeof(list[idx].ctrl_url)); + if (lttng_strncpy(list[idx].ctrl_url, + output->consumer->dst.trace_path, + sizeof(list[idx].ctrl_url))) { + ret = -LTTNG_ERR_INVALID; + goto error; + } } else { /* Control URI. */ ret = uri_to_str_url(&output->consumer->dst.net.control, @@ -3384,7 +3397,7 @@ error: * Return 0 if the metadata can be generated, a LTTNG_ERR code otherwise. */ static -int check_metadata_regenerate_support(struct ltt_session *session) +int check_regenerate_metadata_support(struct ltt_session *session) { int ret; @@ -3423,7 +3436,7 @@ end: } static -int ust_metadata_regenerate(struct ltt_ust_session *usess) +int ust_regenerate_metadata(struct ltt_ust_session *usess) { int ret = 0; struct buffer_reg_uid *uid_reg = NULL; @@ -3484,7 +3497,7 @@ end: } /* - * Command LTTNG_METADATA_REGENERATE from the lttng-ctl library. + * Command LTTNG_REGENERATE_METADATA from the lttng-ctl library. * * Ask the consumer to truncate the existing metadata file(s) and * then regenerate the metadata. Live and per-pid sessions are not @@ -3492,19 +3505,19 @@ end: * * Return 0 on success or else a LTTNG_ERR code. */ -int cmd_metadata_regenerate(struct ltt_session *session) +int cmd_regenerate_metadata(struct ltt_session *session) { int ret; assert(session); - ret = check_metadata_regenerate_support(session); + ret = check_regenerate_metadata_support(session); if (ret) { goto end; } if (session->kernel_session) { - ret = kernctl_session_metadata_regenerate( + ret = kernctl_session_regenerate_metadata( session->kernel_session->fd); if (ret < 0) { ERR("Failed to regenerate the kernel metadata"); @@ -3513,7 +3526,7 @@ int cmd_metadata_regenerate(struct ltt_session *session) } if (session->ust_session) { - ret = ust_metadata_regenerate(session->ust_session); + ret = ust_regenerate_metadata(session->ust_session); if (ret < 0) { ERR("Failed to regenerate the UST metadata"); goto end; @@ -3526,7 +3539,6 @@ end: return ret; } - /* * Send relayd sockets from snapshot output to consumer. Ignore request if the * snapshot output is *not* set with a remote destination. @@ -3588,13 +3600,6 @@ static int record_kernel_snapshot(struct ltt_kernel_session *ksess, assert(output); assert(session); - /* Get the datetime for the snapshot output directory. */ - ret = utils_get_current_time_str("%Y%m%d-%H%M%S", output->datetime, - sizeof(output->datetime)); - if (!ret) { - ret = LTTNG_ERR_INVALID; - goto error; - } /* * Copy kernel session sockets so we can communicate with the right @@ -3642,14 +3647,6 @@ static int record_ust_snapshot(struct ltt_ust_session *usess, assert(output); assert(session); - /* Get the datetime for the snapshot output directory. */ - ret = utils_get_current_time_str("%Y%m%d-%H%M%S", output->datetime, - sizeof(output->datetime)); - if (!ret) { - ret = LTTNG_ERR_INVALID; - goto error; - } - /* * Copy UST session sockets so we can communicate with the right * consumer for the snapshot record command. @@ -3671,9 +3668,6 @@ static int record_ust_snapshot(struct ltt_ust_session *usess, case EINVAL: ret = LTTNG_ERR_INVALID; break; - case ENODATA: - ret = LTTNG_ERR_SNAPSHOT_NODATA; - break; default: ret = LTTNG_ERR_SNAPSHOT_FAIL; break; @@ -3791,12 +3785,21 @@ int cmd_snapshot_record(struct ltt_session *session, unsigned int use_tmp_output = 0; struct snapshot_output tmp_output; unsigned int snapshot_success = 0; + char datetime[16]; assert(session); assert(output); DBG("Cmd snapshot record for session %s", session->name); + /* Get the datetime for the snapshot output directory. */ + ret = utils_get_current_time_str("%Y%m%d-%H%M%S", datetime, + sizeof(datetime)); + if (!ret) { + ret = LTTNG_ERR_INVALID; + goto error; + } + /* * Permission denied to create an output if the session is not * set in no output mode. @@ -3827,138 +3830,104 @@ int cmd_snapshot_record(struct ltt_session *session, } /* Use the global session count for the temporary snapshot. */ tmp_output.nb_snapshot = session->snapshot.nb_snapshot; + + /* Use the global datetime */ + memcpy(tmp_output.datetime, datetime, sizeof(datetime)); use_tmp_output = 1; } - if (session->kernel_session) { - struct ltt_kernel_session *ksess = session->kernel_session; + if (use_tmp_output) { + int64_t nb_packets_per_stream; - if (use_tmp_output) { - int64_t nb_packets_per_stream; + nb_packets_per_stream = get_session_nb_packets_per_stream(session, + tmp_output.max_size); + if (nb_packets_per_stream < 0) { + ret = LTTNG_ERR_MAX_SIZE_INVALID; + goto error; + } - nb_packets_per_stream = get_session_nb_packets_per_stream(session, - tmp_output.max_size); - if (nb_packets_per_stream < 0) { - ret = LTTNG_ERR_MAX_SIZE_INVALID; + if (session->kernel_session) { + ret = record_kernel_snapshot(session->kernel_session, + &tmp_output, session, + wait, nb_packets_per_stream); + if (ret != LTTNG_OK) { goto error; } - ret = record_kernel_snapshot(ksess, &tmp_output, session, + } + + if (session->ust_session) { + ret = record_ust_snapshot(session->ust_session, + &tmp_output, session, wait, nb_packets_per_stream); if (ret != LTTNG_OK) { goto error; } - snapshot_success = 1; - } else { - struct snapshot_output *sout; - struct lttng_ht_iter iter; - - rcu_read_lock(); - cds_lfht_for_each_entry(session->snapshot.output_ht->ht, - &iter.iter, sout, node.node) { - int64_t nb_packets_per_stream; - - /* - * Make a local copy of the output and assign the possible - * temporary value given by the caller. - */ - memset(&tmp_output, 0, sizeof(tmp_output)); - memcpy(&tmp_output, sout, sizeof(tmp_output)); - - if (output->max_size != (uint64_t) -1ULL) { - tmp_output.max_size = output->max_size; - } + } - nb_packets_per_stream = get_session_nb_packets_per_stream(session, - tmp_output.max_size); - if (nb_packets_per_stream < 0) { - ret = LTTNG_ERR_MAX_SIZE_INVALID; - goto error; - } + snapshot_success = 1; + } else { + struct snapshot_output *sout; + struct lttng_ht_iter iter; - /* Use temporary name. */ - if (*output->name != '\0') { - strncpy(tmp_output.name, output->name, - sizeof(tmp_output.name)); - } + rcu_read_lock(); + cds_lfht_for_each_entry(session->snapshot.output_ht->ht, + &iter.iter, sout, node.node) { + int64_t nb_packets_per_stream; - tmp_output.nb_snapshot = session->snapshot.nb_snapshot; + /* + * Make a local copy of the output and assign the possible + * temporary value given by the caller. + */ + memset(&tmp_output, 0, sizeof(tmp_output)); + memcpy(&tmp_output, sout, sizeof(tmp_output)); - ret = record_kernel_snapshot(ksess, &tmp_output, - session, wait, nb_packets_per_stream); - if (ret != LTTNG_OK) { - rcu_read_unlock(); - goto error; - } - snapshot_success = 1; + if (output->max_size != (uint64_t) -1ULL) { + tmp_output.max_size = output->max_size; } - rcu_read_unlock(); - } - } - - if (session->ust_session) { - struct ltt_ust_session *usess = session->ust_session; - - if (use_tmp_output) { - int64_t nb_packets_per_stream; nb_packets_per_stream = get_session_nb_packets_per_stream(session, tmp_output.max_size); if (nb_packets_per_stream < 0) { ret = LTTNG_ERR_MAX_SIZE_INVALID; + rcu_read_unlock(); goto error; } - ret = record_ust_snapshot(usess, &tmp_output, session, - wait, nb_packets_per_stream); - if (ret != LTTNG_OK) { - goto error; - } - snapshot_success = 1; - } else { - struct snapshot_output *sout; - struct lttng_ht_iter iter; - - rcu_read_lock(); - cds_lfht_for_each_entry(session->snapshot.output_ht->ht, - &iter.iter, sout, node.node) { - int64_t nb_packets_per_stream; - /* - * Make a local copy of the output and assign the possible - * temporary value given by the caller. - */ - memset(&tmp_output, 0, sizeof(tmp_output)); - memcpy(&tmp_output, sout, sizeof(tmp_output)); - - if (output->max_size != (uint64_t) -1ULL) { - tmp_output.max_size = output->max_size; - } - - nb_packets_per_stream = get_session_nb_packets_per_stream(session, - tmp_output.max_size); - if (nb_packets_per_stream < 0) { - ret = LTTNG_ERR_MAX_SIZE_INVALID; + /* Use temporary name. */ + if (*output->name != '\0') { + if (lttng_strncpy(tmp_output.name, output->name, + sizeof(tmp_output.name))) { + ret = LTTNG_ERR_INVALID; rcu_read_unlock(); goto error; } + } - /* Use temporary name. */ - if (*output->name != '\0') { - strncpy(tmp_output.name, output->name, - sizeof(tmp_output.name)); - } + tmp_output.nb_snapshot = session->snapshot.nb_snapshot; + memcpy(tmp_output.datetime, datetime, sizeof(datetime)); - tmp_output.nb_snapshot = session->snapshot.nb_snapshot; + if (session->kernel_session) { + ret = record_kernel_snapshot(session->kernel_session, + &tmp_output, session, + wait, nb_packets_per_stream); + if (ret != LTTNG_OK) { + rcu_read_unlock(); + goto error; + } + } - ret = record_ust_snapshot(usess, &tmp_output, session, + if (session->ust_session) { + ret = record_ust_snapshot(session->ust_session, + &tmp_output, session, wait, nb_packets_per_stream); if (ret != LTTNG_OK) { rcu_read_unlock(); goto error; } - snapshot_success = 1; } - rcu_read_unlock(); + snapshot_success = 1; } + rcu_read_unlock(); } if (snapshot_success) {