X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fchannel.cpp;h=540fc973405de16ebcc4d3fddf450827e9018f03;hp=0f150972c74f79d74bf01e0dc06b3dee601f2b15;hb=HEAD;hpb=7966af5763c4aaca39df9bbfa9277ff15715c720 diff --git a/src/bin/lttng-sessiond/channel.cpp b/src/bin/lttng-sessiond/channel.cpp index 0f150972c..4e5401295 100644 --- a/src/bin/lttng-sessiond/channel.cpp +++ b/src/bin/lttng-sessiond/channel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 David Goulet + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2016 Jérémie Galarneau * * SPDX-License-Identifier: GPL-2.0-only @@ -7,40 +7,39 @@ */ #define _LGPL_SOURCE +#include "agent.hpp" +#include "channel.hpp" +#include "kernel.hpp" +#include "lttng-sessiond.hpp" +#include "lttng-ust-ctl.hpp" +#include "lttng-ust-error.hpp" +#include "ust-app.hpp" +#include "utils.hpp" + +#include +#include +#include + #include #include #include -#include -#include -#include - -#include "channel.h" -#include "lttng-sessiond.h" -#include "kernel.h" -#include "lttng-ust-ctl.h" -#include "lttng-ust-error.h" -#include "utils.h" -#include "ust-app.h" -#include "agent.h" - /* * Return allocated channel attributes. */ -struct lttng_channel *channel_new_default_attr(int dom, - enum lttng_buffer_type type) +struct lttng_channel *channel_new_default_attr(int dom, enum lttng_buffer_type type) { struct lttng_channel *chan; const char *channel_name = DEFAULT_CHANNEL_NAME; - struct lttng_channel_extended *extended_attr = NULL; + struct lttng_channel_extended *extended_attr = nullptr; - chan = (lttng_channel *) zmalloc(sizeof(struct lttng_channel)); - if (chan == NULL) { + chan = zmalloc(); + if (chan == nullptr) { PERROR("zmalloc channel init"); goto error_alloc; } - extended_attr = (lttng_channel_extended *) zmalloc(sizeof(struct lttng_channel_extended)); + extended_attr = zmalloc(); if (!extended_attr) { PERROR("zmalloc channel extended init"); goto error; @@ -56,16 +55,14 @@ struct lttng_channel *channel_new_default_attr(int dom, switch (dom) { case LTTNG_DOMAIN_KERNEL: LTTNG_ASSERT(type == LTTNG_BUFFER_GLOBAL); - chan->attr.subbuf_size = - default_get_kernel_channel_subbuf_size(); + chan->attr.subbuf_size = default_get_kernel_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; chan->attr.switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER; chan->attr.live_timer_interval = DEFAULT_KERNEL_CHANNEL_LIVE_TIMER; extended_attr->blocking_timeout = DEFAULT_KERNEL_CHANNEL_BLOCKING_TIMEOUT; - extended_attr->monitor_timer_interval = - DEFAULT_KERNEL_CHANNEL_MONITOR_TIMER; + extended_attr->monitor_timer_interval = DEFAULT_KERNEL_CHANNEL_MONITOR_TIMER; break; case LTTNG_DOMAIN_JUL: channel_name = DEFAULT_JUL_CHANNEL_NAME; @@ -77,18 +74,15 @@ struct lttng_channel *channel_new_default_attr(int dom, channel_name = DEFAULT_PYTHON_CHANNEL_NAME; goto common_ust; case LTTNG_DOMAIN_UST: -common_ust: + common_ust: switch (type) { case LTTNG_BUFFER_PER_UID: chan->attr.subbuf_size = default_get_ust_uid_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_UST_UID_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_UST_UID_CHANNEL_OUTPUT; - chan->attr.switch_timer_interval = - DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER; - chan->attr.read_timer_interval = - DEFAULT_UST_UID_CHANNEL_READ_TIMER; - chan->attr.live_timer_interval = - DEFAULT_UST_UID_CHANNEL_LIVE_TIMER; + chan->attr.switch_timer_interval = DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER; + chan->attr.read_timer_interval = DEFAULT_UST_UID_CHANNEL_READ_TIMER; + chan->attr.live_timer_interval = DEFAULT_UST_UID_CHANNEL_LIVE_TIMER; extended_attr->blocking_timeout = DEFAULT_UST_UID_CHANNEL_BLOCKING_TIMEOUT; extended_attr->monitor_timer_interval = DEFAULT_UST_UID_CHANNEL_MONITOR_TIMER; @@ -98,12 +92,9 @@ common_ust: chan->attr.subbuf_size = default_get_ust_pid_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_UST_PID_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_UST_PID_CHANNEL_OUTPUT; - chan->attr.switch_timer_interval = - DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER; - chan->attr.read_timer_interval = - DEFAULT_UST_PID_CHANNEL_READ_TIMER; - chan->attr.live_timer_interval = - DEFAULT_UST_PID_CHANNEL_LIVE_TIMER; + chan->attr.switch_timer_interval = DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER; + chan->attr.read_timer_interval = DEFAULT_UST_PID_CHANNEL_READ_TIMER; + chan->attr.live_timer_interval = DEFAULT_UST_PID_CHANNEL_LIVE_TIMER; extended_attr->blocking_timeout = DEFAULT_UST_PID_CHANNEL_BLOCKING_TIMEOUT; extended_attr->monitor_timer_interval = DEFAULT_UST_PID_CHANNEL_MONITOR_TIMER; @@ -111,11 +102,10 @@ common_ust: } break; default: - goto error; /* Not implemented */ + goto error; /* Not implemented */ } - if (snprintf(chan->name, sizeof(chan->name), "%s", - channel_name) < 0) { + if (snprintf(chan->name, sizeof(chan->name), "%s", channel_name) < 0) { PERROR("snprintf default channel name"); goto error; } @@ -125,7 +115,7 @@ error: free(extended_attr); free(chan); error_alloc: - return NULL; + return nullptr; } void channel_attr_destroy(struct lttng_channel *channel) @@ -140,8 +130,7 @@ void channel_attr_destroy(struct lttng_channel *channel) /* * Disable kernel channel of the kernel session. */ -int channel_kernel_disable(struct ltt_kernel_session *ksession, - char *channel_name) +int channel_kernel_disable(struct ltt_kernel_session *ksession, char *channel_name) { int ret; struct ltt_kernel_channel *kchan; @@ -150,13 +139,13 @@ int channel_kernel_disable(struct ltt_kernel_session *ksession, LTTNG_ASSERT(channel_name); kchan = trace_kernel_get_channel_by_name(channel_name, ksession); - if (kchan == NULL) { + if (kchan == nullptr) { ret = LTTNG_ERR_KERN_CHAN_NOT_FOUND; goto error; } /* Only if channel is enabled disable it. */ - if (kchan->enabled == 1) { + if (kchan->enabled) { ret = kernel_disable_channel(kchan); if (ret < 0 && ret != -EEXIST) { ret = LTTNG_ERR_KERN_CHAN_DISABLE_FAIL; @@ -173,29 +162,28 @@ error: /* * Enable kernel channel of the kernel session. */ -int channel_kernel_enable(struct ltt_kernel_session *ksession, - struct ltt_kernel_channel *kchan) +enum lttng_error_code channel_kernel_enable(struct ltt_kernel_session *ksession, + struct ltt_kernel_channel *kchan) { - int ret; + enum lttng_error_code ret_code; LTTNG_ASSERT(ksession); LTTNG_ASSERT(kchan); - if (kchan->enabled == 0) { - ret = kernel_enable_channel(kchan); - if (ret < 0) { - ret = LTTNG_ERR_KERN_CHAN_ENABLE_FAIL; + if (!kchan->enabled) { + if (kernel_enable_channel(kchan) < 0) { + ret_code = LTTNG_ERR_KERN_CHAN_ENABLE_FAIL; goto error; } } else { - ret = LTTNG_ERR_KERN_CHAN_EXIST; + ret_code = LTTNG_ERR_KERN_CHAN_EXIST; goto error; } - ret = LTTNG_OK; + ret_code = LTTNG_OK; error: - return ret; + return ret_code; } static int channel_validate(struct lttng_channel *attr) @@ -214,7 +202,7 @@ static int channel_validate(struct lttng_channel *attr) static int channel_validate_kernel(struct lttng_channel *attr) { /* Kernel channels do not support blocking timeout. */ - if (((struct lttng_channel_extended *)attr->attr.extended.ptr)->blocking_timeout) { + if (((struct lttng_channel_extended *) attr->attr.extended.ptr)->blocking_timeout) { return -1; } return 0; @@ -223,20 +211,20 @@ static int channel_validate_kernel(struct lttng_channel *attr) /* * Create kernel channel of the kernel session and notify kernel thread. */ -int channel_kernel_create(struct ltt_kernel_session *ksession, - struct lttng_channel *attr, int kernel_pipe) +enum lttng_error_code channel_kernel_create(struct ltt_kernel_session *ksession, + struct lttng_channel *attr, + int kernel_pipe) { - int ret; - struct lttng_channel *defattr = NULL; + enum lttng_error_code ret_code; + struct lttng_channel *defattr = nullptr; LTTNG_ASSERT(ksession); /* Creating channel attributes if needed */ - if (attr == NULL) { - defattr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL, - LTTNG_BUFFER_GLOBAL); - if (defattr == NULL) { - ret = LTTNG_ERR_FATAL; + if (attr == nullptr) { + defattr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL, LTTNG_BUFFER_GLOBAL); + if (defattr == nullptr) { + ret_code = LTTNG_ERR_FATAL; goto error; } attr = defattr; @@ -252,42 +240,40 @@ int channel_kernel_create(struct ltt_kernel_session *ksession, /* Validate common channel properties. */ if (channel_validate(attr) < 0) { - ret = LTTNG_ERR_INVALID; + ret_code = LTTNG_ERR_INVALID; goto error; } if (channel_validate_kernel(attr) < 0) { - ret = LTTNG_ERR_INVALID; + ret_code = LTTNG_ERR_INVALID; goto error; } - /* Channel not found, creating it */ - ret = kernel_create_channel(ksession, attr); - if (ret < 0) { - ret = LTTNG_ERR_KERN_CHAN_FAIL; + /* Channel not found, creating it. */ + if (kernel_create_channel(ksession, attr) < 0) { + ret_code = LTTNG_ERR_KERN_CHAN_FAIL; goto error; } /* Notify kernel thread that there is a new channel */ - ret = notify_thread_pipe(kernel_pipe); - if (ret < 0) { - ret = LTTNG_ERR_FATAL; + if (notify_thread_pipe(kernel_pipe) < 0) { + ret_code = LTTNG_ERR_FATAL; goto error; } - ret = LTTNG_OK; + ret_code = LTTNG_OK; error: channel_attr_destroy(defattr); - return ret; + return ret_code; } /* * Enable UST channel for session and domain. */ -int channel_ust_enable(struct ltt_ust_session *usess, - struct ltt_ust_channel *uchan) +enum lttng_error_code channel_ust_enable(struct ltt_ust_session *usess, + struct ltt_ust_channel *uchan) { - int ret = LTTNG_OK; + enum lttng_error_code ret_code = LTTNG_OK; LTTNG_ASSERT(usess); LTTNG_ASSERT(uchan); @@ -295,10 +281,10 @@ int channel_ust_enable(struct ltt_ust_session *usess, /* If already enabled, everything is OK */ if (uchan->enabled) { DBG3("Channel %s already enabled. Skipping", uchan->name); - ret = LTTNG_ERR_UST_CHAN_EXIST; + ret_code = LTTNG_ERR_UST_CHAN_EXIST; goto end; } else { - uchan->enabled = 1; + uchan->enabled = true; DBG2("Channel %s enabled successfully", uchan->name); } @@ -323,30 +309,31 @@ int channel_ust_enable(struct ltt_ust_session *usess, */ (void) ust_app_enable_channel_glb(usess, uchan); - end: - return ret; + return ret_code; } /* * Create UST channel for session and domain. */ -int channel_ust_create(struct ltt_ust_session *usess, - struct lttng_channel *attr, enum lttng_buffer_type type) +enum lttng_error_code channel_ust_create(struct ltt_ust_session *usess, + struct lttng_channel *attr, + enum lttng_buffer_type type) { - int ret = LTTNG_OK; - struct ltt_ust_channel *uchan = NULL; - struct lttng_channel *defattr = NULL; + enum lttng_error_code ret_code = LTTNG_OK; + struct ltt_ust_channel *uchan = nullptr; + struct lttng_channel *defattr = nullptr; enum lttng_domain_type domain = LTTNG_DOMAIN_UST; bool chan_published = false; + lttng::urcu::read_lock_guard read_lock; LTTNG_ASSERT(usess); /* Creating channel attributes if needed */ - if (attr == NULL) { + if (attr == nullptr) { defattr = channel_new_default_attr(LTTNG_DOMAIN_UST, type); - if (defattr == NULL) { - ret = LTTNG_ERR_FATAL; + if (defattr == nullptr) { + ret_code = LTTNG_ERR_FATAL; goto error; } attr = defattr; @@ -379,7 +366,7 @@ int channel_ust_create(struct ltt_ust_session *usess, /* Validate common channel properties. */ if (channel_validate(attr) < 0) { - ret = LTTNG_ERR_INVALID; + ret_code = LTTNG_ERR_INVALID; goto error; } @@ -388,9 +375,8 @@ int channel_ust_create(struct ltt_ust_session *usess, * and nonzero. We validate right here for UST, because applications will * not report the error to the user (unlike kernel tracing). */ - if (!attr->attr.subbuf_size || - (attr->attr.subbuf_size & (attr->attr.subbuf_size - 1))) { - ret = LTTNG_ERR_INVALID; + if (!attr->attr.subbuf_size || (attr->attr.subbuf_size & (attr->attr.subbuf_size - 1))) { + ret_code = LTTNG_ERR_INVALID; goto error; } @@ -398,18 +384,17 @@ int channel_ust_create(struct ltt_ust_session *usess, * Invalid subbuffer size if it's lower then the page size. */ if (attr->attr.subbuf_size < the_page_size) { - ret = LTTNG_ERR_INVALID; + ret_code = LTTNG_ERR_INVALID; goto error; } - if (!attr->attr.num_subbuf || - (attr->attr.num_subbuf & (attr->attr.num_subbuf - 1))) { - ret = LTTNG_ERR_INVALID; + if (!attr->attr.num_subbuf || (attr->attr.num_subbuf & (attr->attr.num_subbuf - 1))) { + ret_code = LTTNG_ERR_INVALID; goto error; } if (attr->attr.output != LTTNG_EVENT_MMAP) { - ret = LTTNG_ERR_NOT_SUPPORTED; + ret_code = LTTNG_ERR_NOT_SUPPORTED; goto error; } @@ -418,8 +403,8 @@ int channel_ust_create(struct ltt_ust_session *usess, * we won't be able to write the packets on disk */ if ((attr->attr.tracefile_size > 0) && - (attr->attr.tracefile_size < attr->attr.subbuf_size)) { - ret = LTTNG_ERR_INVALID; + (attr->attr.tracefile_size < attr->attr.subbuf_size)) { + ret_code = LTTNG_ERR_INVALID; goto error; } @@ -430,26 +415,29 @@ int channel_ust_create(struct ltt_ust_session *usess, case LTTNG_BUFFER_PER_UID: break; default: - ret = LTTNG_ERR_BUFFER_NOT_SUPPORTED; + ret_code = LTTNG_ERR_BUFFER_NOT_SUPPORTED; goto error; } /* Create UST channel */ uchan = trace_ust_create_channel(attr, domain); - if (uchan == NULL) { - ret = LTTNG_ERR_FATAL; + if (uchan == nullptr) { + ret_code = LTTNG_ERR_FATAL; goto error; } - uchan->enabled = 1; - if (trace_ust_is_max_id(usess->used_channel_id)) { - ret = LTTNG_ERR_UST_CHAN_FAIL; + uchan->enabled = true; + if (trace_ust_is_max_id(usess->used_event_container_id)) { + ret_code = LTTNG_ERR_UST_CHAN_FAIL; goto error; } - uchan->id = trace_ust_get_next_chan_id(usess); + + uchan->id = trace_ust_get_next_event_container_id(usess); DBG2("Channel %s is being created for UST with buffer %d and id %" PRIu64, - uchan->name, type, uchan->id); + uchan->name, + type, + uchan->id); /* Flag session buffer type. */ if (!usess->buffer_type_changed) { @@ -457,14 +445,12 @@ int channel_ust_create(struct ltt_ust_session *usess, usess->buffer_type_changed = 1; } else if (usess->buffer_type != type) { /* Buffer type was already set. Refuse to create channel. */ - ret = LTTNG_ERR_BUFFER_TYPE_MISMATCH; + ret_code = LTTNG_ERR_BUFFER_TYPE_MISMATCH; goto error_free_chan; } /* Adding the channel to the channel hash table. */ - rcu_read_lock(); - if (strncmp(uchan->name, DEFAULT_METADATA_NAME, - sizeof(uchan->name))) { + if (strncmp(uchan->name, DEFAULT_METADATA_NAME, sizeof(uchan->name)) != 0) { lttng_ht_add_unique_str(usess->domain_global.channels, &uchan->node); chan_published = true; } else { @@ -473,10 +459,8 @@ int channel_ust_create(struct ltt_ust_session *usess, * application exists we can access that data in the shadow copy during * the global update of newly registered application. */ - memcpy(&usess->metadata_attr, &uchan->attr, - sizeof(usess->metadata_attr)); + memcpy(&usess->metadata_attr, &uchan->attr, sizeof(usess->metadata_attr)); } - rcu_read_unlock(); DBG2("Channel %s created successfully", uchan->name); if (domain != LTTNG_DOMAIN_UST) { @@ -485,7 +469,7 @@ int channel_ust_create(struct ltt_ust_session *usess, if (!agt) { agt = agent_create(domain); if (!agt) { - ret = LTTNG_ERR_NOMEM; + ret_code = LTTNG_ERR_NOMEM; goto error_remove_chan; } agent_add(agt, usess->agents); @@ -503,14 +487,13 @@ error_free_chan: trace_ust_destroy_channel(uchan); error: channel_attr_destroy(defattr); - return ret; + return ret_code; } /* * Disable UST channel for session and domain. */ -int channel_ust_disable(struct ltt_ust_session *usess, - struct ltt_ust_channel *uchan) +int channel_ust_disable(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan) { int ret = LTTNG_OK; @@ -518,12 +501,12 @@ int channel_ust_disable(struct ltt_ust_session *usess, LTTNG_ASSERT(uchan); /* Already disabled */ - if (uchan->enabled == 0) { + if (!uchan->enabled) { DBG2("Channel UST %s already disabled", uchan->name); goto end; } - uchan->enabled = 0; + uchan->enabled = false; /* * If session is inactive we don't notify the tracer right away. We @@ -549,3 +532,54 @@ end: error: return ret; } + +struct lttng_channel *trace_ust_channel_to_lttng_channel(const struct ltt_ust_channel *uchan) +{ + struct lttng_channel *channel = nullptr, *ret = nullptr; + + channel = lttng_channel_create_internal(); + if (!channel) { + ERR("Failed to create lttng_channel during conversion from ltt_ust_channel to lttng_channel"); + goto end; + } + + if (lttng_strncpy(channel->name, uchan->name, LTTNG_SYMBOL_NAME_LEN)) { + ERR("Failed to set channel name during conversion from ltt_ust_channel to lttng_channel"); + goto end; + } + + channel->attr.overwrite = uchan->attr.overwrite; + channel->attr.subbuf_size = uchan->attr.subbuf_size; + channel->attr.num_subbuf = uchan->attr.num_subbuf; + channel->attr.switch_timer_interval = uchan->attr.switch_timer_interval; + channel->attr.read_timer_interval = uchan->attr.read_timer_interval; + channel->enabled = uchan->enabled; + channel->attr.tracefile_size = uchan->tracefile_size; + channel->attr.tracefile_count = uchan->tracefile_count; + + /* + * Map enum lttng_ust_output to enum lttng_event_output. + */ + switch (uchan->attr.output) { + case LTTNG_UST_ABI_MMAP: + channel->attr.output = LTTNG_EVENT_MMAP; + break; + default: + /* + * LTTNG_UST_MMAP is the only supported UST + * output mode. + */ + abort(); + break; + } + + lttng_channel_set_blocking_timeout(channel, uchan->attr.u.s.blocking_timeout); + lttng_channel_set_monitor_timer_interval(channel, uchan->monitor_timer_interval); + + ret = channel; + channel = nullptr; + +end: + lttng_channel_destroy(channel); + return ret; +}