#include "buffer-registry.hpp"
#include "channel.hpp"
#include "cmd.hpp"
+#include "consumer-output.hpp"
#include "consumer.hpp"
#include "event-notifier-error-accounting.hpp"
#include "event.hpp"
* Create a session path used by list_lttng_sessions for the case that the
* session consumer is on the network.
*/
-static int build_network_session_path(char *dst, size_t size, struct ltt_session *session)
+static int
+build_network_session_path(char *dst, size_t size, const ltt_session::locked_ref& session)
{
int ret, kdata_port, udata_port;
struct lttng_uri *kuri = nullptr, *uuri = nullptr, *uri = nullptr;
char tmp_uurl[PATH_MAX], tmp_urls[PATH_MAX];
- LTTNG_ASSERT(session);
LTTNG_ASSERT(dst);
memset(tmp_urls, 0, sizeof(tmp_urls));
* Get run-time attributes if the session has been started (discarded events,
* lost packets).
*/
-static int get_kernel_runtime_stats(struct ltt_session *session,
+static int get_kernel_runtime_stats(const ltt_session::locked_ref& session,
struct ltt_kernel_channel *kchan,
uint64_t *discarded_events,
uint64_t *lost_packets)
* Get run-time attributes if the session has been started (discarded events,
* lost packets).
*/
-static int get_ust_runtime_stats(struct ltt_session *session,
+static int get_ust_runtime_stats(const ltt_session::locked_ref& session,
struct ltt_ust_channel *uchan,
uint64_t *discarded_events,
uint64_t *lost_packets)
* Add URI so the consumer output object. Set the correct path depending on the
* domain adding the default trace directory.
*/
-static enum lttng_error_code add_uri_to_consumer(const struct ltt_session *session,
+static enum lttng_error_code add_uri_to_consumer(const ltt_session::locked_ref& session,
struct consumer_output *consumer,
struct lttng_uri *uri,
enum lttng_domain_type domain)
* the relayd and send them to the right domain consumer. Consumer type MUST be
* network.
*/
-int cmd_setup_relayd(struct ltt_session *session)
+int cmd_setup_relayd(const ltt_session::locked_ref& session)
{
int ret = LTTNG_OK;
struct ltt_ust_session *usess;
struct lttng_ht_iter iter;
LTTNG_OPTIONAL(uint64_t) current_chunk_id = {};
- LTTNG_ASSERT(session);
-
usess = session->ust_session;
ksess = session->kernel_session;
/*
* Command LTTNG_DISABLE_CHANNEL processed by the client thread.
*/
-int cmd_disable_channel(struct ltt_session *session,
+int cmd_disable_channel(const ltt_session::locked_ref& session,
enum lttng_domain_type domain,
char *channel_name)
{
int wpipe)
{
enum lttng_error_code ret_code;
- struct ltt_ust_session *usess = session.get()->ust_session;
+ struct ltt_ust_session *usess = session->ust_session;
struct lttng_ht *chan_ht;
size_t len;
struct lttng_channel *attr = nullptr;
* live timer does the same thing but sends also synchronisation
* beacons for inactive streams.
*/
- if (session.get()->live_timer > 0) {
- attr->attr.live_timer_interval = session.get()->live_timer;
+ if (session->live_timer > 0) {
+ attr->attr.live_timer_interval = session->live_timer;
attr->attr.switch_timer_interval = 0;
}
"Setting the monitor interval timer to 0 "
"(disabled) for channel '%s' of session '%s'",
attr->name,
- session.get()->name);
+ session->name);
lttng_channel_set_monitor_timer_interval(attr, 0);
}
break;
}
enum lttng_error_code
-cmd_process_attr_tracker_get_tracking_policy(struct ltt_session *session,
+cmd_process_attr_tracker_get_tracking_policy(const ltt_session::locked_ref& session,
enum lttng_domain_type domain,
enum lttng_process_attr process_attr,
enum lttng_tracking_policy *policy)
}
enum lttng_error_code
-cmd_process_attr_tracker_set_tracking_policy(struct ltt_session *session,
+cmd_process_attr_tracker_set_tracking_policy(const ltt_session::locked_ref& session,
enum lttng_domain_type domain,
enum lttng_process_attr process_attr,
enum lttng_tracking_policy policy)
}
enum lttng_error_code
-cmd_process_attr_tracker_inclusion_set_add_value(struct ltt_session *session,
+cmd_process_attr_tracker_inclusion_set_add_value(const ltt_session::locked_ref& session,
enum lttng_domain_type domain,
enum lttng_process_attr process_attr,
const struct process_attr_value *value)
}
enum lttng_error_code
-cmd_process_attr_tracker_inclusion_set_remove_value(struct ltt_session *session,
+cmd_process_attr_tracker_inclusion_set_remove_value(const ltt_session::locked_ref& session,
enum lttng_domain_type domain,
enum lttng_process_attr process_attr,
const struct process_attr_value *value)
}
enum lttng_error_code
-cmd_process_attr_tracker_get_inclusion_set(struct ltt_session *session,
+cmd_process_attr_tracker_get_inclusion_set(const ltt_session::locked_ref& session,
enum lttng_domain_type domain,
enum lttng_process_attr process_attr,
struct lttng_process_attr_values **values)
struct lttng_event_exclusion *exclusion)
{
int ret;
- ltt_session& session = *locked_session.get();
+ const ltt_session& session = *locked_session;
const char *event_name;
const char *channel_name = cmd_ctx->lsm.u.disable.channel_name;
const enum lttng_domain_type domain = cmd_ctx->lsm.domain.type;
{
int ret, chan_kern_created = 0, chan_ust_created = 0;
const enum lttng_domain_type domain = cmd_ctx->lsm.domain.type;
- const struct ltt_session& session = *locked_session.get();
+ const struct ltt_session& session = *locked_session;
const char *channel_name = cmd_ctx->lsm.u.context.channel_name;
/*
{
int ret = 0, channel_created = 0;
struct lttng_channel *attr = nullptr;
- ltt_session& session = *locked_session.get();
+ ltt_session& session = *locked_session;
LTTNG_ASSERT(event);
LTTNG_ASSERT(channel_name);
/*
* Command LTTNG_START_TRACE processed by the client thread.
- *
- * Called with session mutex held.
*/
-int cmd_start_trace(struct ltt_session *session)
+int cmd_start_trace(const ltt_session::locked_ref& session)
{
enum lttng_error_code ret;
unsigned long nb_chan = 0;
const bool session_rotated_after_last_stop = session->rotated_after_last_stop;
const bool session_cleared_after_last_stop = session->cleared_after_last_stop;
- LTTNG_ASSERT(session);
-
/* Ease our life a bit ;) */
ksession = session->kernel_session;
usess = session->ust_session;
/*
* Command LTTNG_STOP_TRACE processed by the client thread.
*/
-int cmd_stop_trace(struct ltt_session *session)
+int cmd_stop_trace(const ltt_session::locked_ref& session)
{
int ret;
struct ltt_kernel_session *ksession;
struct ltt_ust_session *usess;
- LTTNG_ASSERT(session);
-
DBG("Begin stop session \"%s\" (id %" PRIu64 ")", session->name, session->id);
/* Short cut */
ksession = session->kernel_session;
* Set the base_path of the session only if subdir of a control uris is set.
* Return LTTNG_OK on success, otherwise LTTNG_ERR_*.
*/
-static int
-set_session_base_path_from_uris(struct ltt_session *session, size_t nb_uri, struct lttng_uri *uris)
+static int set_session_base_path_from_uris(const ltt_session::locked_ref& session,
+ size_t nb_uri,
+ struct lttng_uri *uris)
{
int ret;
size_t i;
/*
* Command LTTNG_SET_CONSUMER_URI processed by the client thread.
*/
-int cmd_set_consumer_uri(struct ltt_session *session, size_t nb_uri, struct lttng_uri *uris)
+int cmd_set_consumer_uri(const ltt_session::locked_ref& session,
+ size_t nb_uri,
+ struct lttng_uri *uris)
{
int ret, i;
struct ltt_kernel_session *ksess = session->kernel_session;
struct ltt_ust_session *usess = session->ust_session;
- LTTNG_ASSERT(session);
LTTNG_ASSERT(uris);
LTTNG_ASSERT(nb_uri > 0);
}
static enum lttng_error_code
-set_session_output_from_descriptor(struct ltt_session *session,
+set_session_output_from_descriptor(const ltt_session::locked_ref& session,
const struct lttng_session_descriptor *descriptor)
{
int ret;
/* Announce the session's destruction to the notification thread when it is destroyed. */
ret = session_add_destroy_notifier(
- new_session,
- [](const struct ltt_session *session, void *user_data __attribute__((unused))) {
+ [new_session]() {
+ session_get(new_session);
+ new_session->lock();
+ return ltt_session::locked_ref(*new_session);
+ }(),
+ [](const ltt_session::locked_ref& session,
+ void *user_data __attribute__((unused))) {
(void) notification_thread_command_remove_session(
the_notification_thread_handle, session->id);
},
break;
}
- ret_code = set_session_output_from_descriptor(new_session, descriptor);
+ ret_code = set_session_output_from_descriptor(
+ [new_session]() {
+ session_get(new_session);
+ new_session->lock();
+ return ltt_session::locked_ref(*new_session);
+ }(),
+ descriptor);
if (ret_code != LTTNG_OK) {
goto end;
}
return ret_code;
}
-static void cmd_destroy_session_reply(const struct ltt_session *session, void *_reply_context)
+static void cmd_destroy_session_reply(const ltt_session::locked_ref& session, void *_reply_context)
{
int ret;
ssize_t comm_ret;
*
* Called with session lock held.
*/
-int cmd_destroy_session(struct ltt_session *session, int *sock_fd)
+int cmd_destroy_session(const ltt_session::locked_ref& session, int *sock_fd)
{
int ret;
enum lttng_error_code destruction_last_error = LTTNG_OK;
reply_context->reply_sock_fd = *sock_fd;
}
- /* Safety net */
- LTTNG_ASSERT(session);
-
DBG("Begin destroy session %s (id %" PRIu64 ")", session->name, session->id);
if (session->active) {
DBG("Session \"%s\" is active, attempting to stop it before destroying it",
* still holds a reference to the session, thus delaying its destruction
* _at least_ up to the point when that reference is released.
*/
- session_destroy(session);
+ session_destroy(&session.get());
if (reply_context) {
reply_context->destruction_status = destruction_last_error;
ret = session_add_destroy_notifier(
/*
* Command LTTNG_REGISTER_CONSUMER processed by the client thread.
*/
-int cmd_register_consumer(struct ltt_session *session,
+int cmd_register_consumer(const ltt_session::locked_ref& session,
enum lttng_domain_type domain,
const char *sock_path,
struct consumer_data *cdata)
int ret, sock;
struct consumer_socket *socket = nullptr;
- LTTNG_ASSERT(session);
LTTNG_ASSERT(cdata);
LTTNG_ASSERT(sock_path);
/*
* Command LTTNG_LIST_DOMAINS processed by the client thread.
*/
-ssize_t cmd_list_domains(struct ltt_session *session, struct lttng_domain **domains)
+ssize_t cmd_list_domains(const ltt_session::locked_ref& session, struct lttng_domain **domains)
{
int ret, index = 0;
ssize_t nb_dom = 0;
* Command LTTNG_LIST_CHANNELS processed by the client thread.
*/
enum lttng_error_code cmd_list_channels(enum lttng_domain_type domain,
- struct ltt_session *session,
+ const ltt_session::locked_ref& session,
struct lttng_payload *payload)
{
int ret = 0;
size_t cmd_header_offset;
enum lttng_error_code ret_code;
- assert(session);
- assert(payload);
+ LTTNG_ASSERT(payload);
DBG("Listing channels for session %s", session->name);
* Command LTTNG_LIST_EVENTS processed by the client thread.
*/
enum lttng_error_code cmd_list_events(enum lttng_domain_type domain,
- struct ltt_session *session,
+ const ltt_session::locked_ref& session,
char *channel_name,
struct lttng_payload *reply_payload)
{
{
int ret;
unsigned int i = 0;
- struct ltt_session *session;
+ struct ltt_session *raw_session_ptr;
struct ltt_session_list *list = session_get_list();
struct lttng_session_extended *extended = (typeof(extended)) (&sessions[session_count]);
* Iterate over session list and append data after the control struct in
* the buffer.
*/
- cds_list_for_each_entry (session, &list->head, list) {
- if (!session_get(session)) {
- continue;
- }
+ cds_list_for_each_entry (raw_session_ptr, &list->head, list) {
+ auto session = [raw_session_ptr]() {
+ session_get(raw_session_ptr);
+ raw_session_ptr->lock();
+ return ltt_session::locked_ref(*raw_session_ptr);
+ }();
+
/*
* Only list the sessions the user can control.
*/
if (!session_access_ok(session, uid) || session->destroyed) {
- session_put(session);
continue;
}
}
if (ret < 0) {
PERROR("snprintf session path");
- session_put(session);
continue;
}
extended[i].creation_time.value = (uint64_t) session->creation_time;
extended[i].creation_time.is_set = 1;
i++;
- session_put(session);
}
}
* Command LTTNG_DATA_PENDING returning 0 if the data is NOT pending meaning
* ready for trace analysis (or any kind of reader) or else 1 for pending data.
*/
-int cmd_data_pending(struct ltt_session *session)
+int cmd_data_pending(const ltt_session::locked_ref& session)
{
int ret;
struct ltt_kernel_session *ksess = session->kernel_session;
struct ltt_ust_session *usess = session->ust_session;
- LTTNG_ASSERT(session);
-
DBG("Data pending for session %s", session->name);
/* Session MUST be stopped to ask for data availability. */
*
* Return LTTNG_OK on success or else a LTTNG_ERR code.
*/
-int cmd_snapshot_add_output(struct ltt_session *session,
+int cmd_snapshot_add_output(const ltt_session::locked_ref& session,
const struct lttng_snapshot_output *output,
uint32_t *id)
{
int ret;
struct snapshot_output *new_output;
- LTTNG_ASSERT(session);
LTTNG_ASSERT(output);
DBG("Cmd snapshot add output for session %s", session->name);
*
* Return LTTNG_OK on success or else a LTTNG_ERR code.
*/
-int cmd_snapshot_del_output(struct ltt_session *session, const struct lttng_snapshot_output *output)
+int cmd_snapshot_del_output(const ltt_session::locked_ref& session,
+ const struct lttng_snapshot_output *output)
{
int ret;
struct snapshot_output *sout = nullptr;
- LTTNG_ASSERT(session);
LTTNG_ASSERT(output);
lttng::urcu::read_lock_guard read_lock;
*
* Return the size of the newly allocated outputs or a negative LTTNG_ERR code.
*/
-ssize_t cmd_snapshot_list_outputs(struct ltt_session *session,
+ssize_t cmd_snapshot_list_outputs(const ltt_session::locked_ref& session,
struct lttng_snapshot_output **outputs)
{
int ret, idx = 0;
struct lttng_ht_iter iter;
struct snapshot_output *output;
- LTTNG_ASSERT(session);
LTTNG_ASSERT(outputs);
DBG("Cmd snapshot list outputs for session %s", session->name);
*
* Return 0 if the metadata can be generated, a LTTNG_ERR code otherwise.
*/
-static int check_regenerate_metadata_support(struct ltt_session *session)
+static int check_regenerate_metadata_support(const ltt_session::locked_ref& session)
{
int ret;
- LTTNG_ASSERT(session);
-
if (session->live_timer != 0) {
ret = LTTNG_ERR_LIVE_SESSION;
goto end;
*
* Return LTTNG_OK on success or else a LTTNG_ERR code.
*/
-int cmd_regenerate_metadata(struct ltt_session *session)
+int cmd_regenerate_metadata(const ltt_session::locked_ref& session)
{
int ret;
- LTTNG_ASSERT(session);
-
ret = check_regenerate_metadata_support(session);
if (ret) {
goto end;
*
* Return LTTNG_OK on success or else a LTTNG_ERR code.
*/
-int cmd_regenerate_statedump(struct ltt_session *session)
+int cmd_regenerate_statedump(const ltt_session::locked_ref& session)
{
int ret;
- LTTNG_ASSERT(session);
-
if (!session->active) {
ret = LTTNG_ERR_SESSION_NOT_STARTED;
goto end;
* Return LTTNG_OK on success or a LTTNG_ERR code.
*/
static enum lttng_error_code set_relayd_for_snapshot(struct consumer_output *output,
- const struct ltt_session *session)
+ const ltt_session::locked_ref& session)
{
enum lttng_error_code status = LTTNG_OK;
struct lttng_ht_iter iter;
const char *base_path;
LTTNG_ASSERT(output);
- LTTNG_ASSERT(session);
DBG2("Set relayd object from snapshot output");
*/
static enum lttng_error_code record_kernel_snapshot(struct ltt_kernel_session *ksess,
const struct consumer_output *output,
- const struct ltt_session *session,
uint64_t nb_packets_per_stream)
{
enum lttng_error_code status;
LTTNG_ASSERT(ksess);
LTTNG_ASSERT(output);
- LTTNG_ASSERT(session);
status = kernel_snapshot_record(ksess, output, nb_packets_per_stream);
return status;
*/
static enum lttng_error_code record_ust_snapshot(struct ltt_ust_session *usess,
const struct consumer_output *output,
- const struct ltt_session *session,
uint64_t nb_packets_per_stream)
{
enum lttng_error_code status;
LTTNG_ASSERT(usess);
LTTNG_ASSERT(output);
- LTTNG_ASSERT(session);
status = ust_app_snapshot_record(usess, output, nb_packets_per_stream);
return status;
}
-static uint64_t get_session_size_one_more_packet_per_stream(const struct ltt_session *session,
+static uint64_t get_session_size_one_more_packet_per_stream(const ltt_session::locked_ref& session,
uint64_t cur_nr_packets)
{
uint64_t tot_size = 0;
* an approximation: for instance, applications could appear/disappear
* in between this call and actually grabbing data.
*/
-static int64_t get_session_nb_packets_per_stream(const struct ltt_session *session,
+static int64_t get_session_nb_packets_per_stream(const ltt_session::locked_ref& session,
uint64_t max_size)
{
int64_t size_left;
return cur_nb_packets;
}
-static enum lttng_error_code snapshot_record(struct ltt_session *session,
+static enum lttng_error_code snapshot_record(const ltt_session::locked_ref& session,
const struct snapshot_output *snapshot_output)
{
int64_t nb_packets_per_stream;
if (session->kernel_session) {
ret_code = record_kernel_snapshot(session->kernel_session,
snapshot_kernel_consumer_output,
- session,
nb_packets_per_stream);
if (ret_code != LTTNG_OK) {
goto error_close_trace_chunk;
}
if (session->ust_session) {
- ret_code = record_ust_snapshot(session->ust_session,
- snapshot_ust_consumer_output,
- session,
- nb_packets_per_stream);
+ ret_code = record_ust_snapshot(
+ session->ust_session, snapshot_ust_consumer_output, nb_packets_per_stream);
if (ret_code != LTTNG_OK) {
goto error_close_trace_chunk;
}
*
* Return LTTNG_OK on success or else a LTTNG_ERR code.
*/
-int cmd_snapshot_record(struct ltt_session *session,
+int cmd_snapshot_record(const ltt_session::locked_ref& session,
const struct lttng_snapshot_output *output,
int wait __attribute__((unused)))
{
char datetime[16];
struct snapshot_output *tmp_output = nullptr;
- LTTNG_ASSERT(session);
LTTNG_ASSERT(output);
DBG("Cmd snapshot record for session %s", session->name);
/*
* Command LTTNG_SET_SESSION_SHM_PATH processed by the client thread.
*/
-int cmd_set_session_shm_path(struct ltt_session *session, const char *shm_path)
+int cmd_set_session_shm_path(const ltt_session::locked_ref& session, const char *shm_path)
{
- /* Safety net */
- LTTNG_ASSERT(session);
-
/*
* Can only set shm path before session is started.
*/
*
* Returns LTTNG_OK on success or else a negative LTTng error code.
*/
-int cmd_rotate_session(struct ltt_session *session,
+int cmd_rotate_session(const ltt_session::locked_ref& session,
struct lttng_rotate_session_return *rotate_return,
bool quiet_rotation,
enum lttng_trace_chunk_command_type command)
bool failed_to_rotate = false;
enum lttng_error_code rotation_fail_code = LTTNG_OK;
- LTTNG_ASSERT(session);
-
if (!session->has_been_started) {
cmd_ret = LTTNG_ERR_START_SESSION_ONCE;
goto end;
ret = (cmd_ret == LTTNG_OK) ? cmd_ret : -((int) cmd_ret);
return ret;
error:
- if (session_reset_rotation_state(*session, LTTNG_ROTATION_STATE_ERROR)) {
+ if (session_reset_rotation_state(session, LTTNG_ROTATION_STATE_ERROR)) {
ERR("Failed to reset rotation state of session \"%s\"", session->name);
}
goto end;
*
* Return LTTNG_OK on success or else an LTTNG_ERR code.
*/
-int cmd_rotate_get_info(struct ltt_session *session,
+int cmd_rotate_get_info(const ltt_session::locked_ref& session,
struct lttng_rotation_get_info_return *info_return,
uint64_t rotation_id)
{
*
* Return LTTNG_OK on success or else a positive LTTNG_ERR code.
*/
-int cmd_rotation_set_schedule(struct ltt_session *session,
+int cmd_rotation_set_schedule(const ltt_session::locked_ref& session,
bool activate,
enum lttng_rotation_schedule_type schedule_type,
uint64_t new_value)
int ret;
uint64_t *parameter_value;
- LTTNG_ASSERT(session);
-
DBG("Cmd rotate set schedule session %s", session->name);
if (session->live_timer || !session->output_traces) {