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);
if (!usess || !session->has_been_started) {
*discarded_events = 0;
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;
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;
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:
{
int wpipe, bool internal_event)
{
int ret, channel_created = 0;
- struct lttng_channel *attr;
+ struct lttng_channel *attr = NULL;
assert(session);
assert(event);
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;
}
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(
free(filter_expression);
free(filter);
free(exclusion);
+ free(attr);
rcu_read_unlock();
return ret;
}
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) {
}
}
- /* 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) {
}
}
- 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;
}
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,
* 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;
}
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;
}
/*
- * 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
*
* 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");
}
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;
return ret;
}
+/*
+ * Command LTTNG_REGENERATE_STATEDUMP from the lttng-ctl library.
+ *
+ * Ask the tracer to regenerate a new statedump.
+ *
+ * Return 0 on success or else a LTTNG_ERR code.
+ */
+int cmd_regenerate_statedump(struct ltt_session *session)
+{
+ int ret;
+
+ assert(session);
+
+ if (!session->active) {
+ ret = LTTNG_ERR_SESSION_NOT_STARTED;
+ goto end;
+ }
+ ret = 0;
+
+ if (session->kernel_session) {
+ ret = kernctl_session_regenerate_statedump(
+ session->kernel_session->fd);
+ /*
+ * Currently, the statedump in kernel can only fail if out
+ * of memory.
+ */
+ if (ret < 0) {
+ if (ret == -ENOMEM) {
+ ret = LTTNG_ERR_REGEN_STATEDUMP_NOMEM;
+ } else {
+ ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL;
+ }
+ ERR("Failed to regenerate the kernel statedump");
+ goto end;
+ }
+ }
+
+ if (session->ust_session) {
+ ret = ust_app_regenerate_statedump_all(session->ust_session);
+ /*
+ * Currently, the statedump in UST always returns 0.
+ */
+ if (ret < 0) {
+ ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL;
+ ERR("Failed to regenerate the UST statedump");
+ goto end;
+ }
+ }
+ DBG("Cmd regenerate statedump for session %s", session->name);
+ ret = LTTNG_OK;
+
+end:
+ return ret;
+}
/*
* Send relayd sockets from snapshot output to consumer. Ignore request if the
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
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.
case EINVAL:
ret = LTTNG_ERR_INVALID;
break;
- case ENODATA:
- ret = LTTNG_ERR_SNAPSHOT_NODATA;
- break;
default:
ret = LTTNG_ERR_SNAPSHOT_FAIL;
break;
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.
}
/* 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) {