/*
- * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
- * Copyright (C) 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright (C) 2011 EfficiOS Inc.
+ * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _LGPL_SOURCE
#include "channel.h"
#include "lttng-sessiond.h"
#include "kernel.h"
-#include "ust-ctl.h"
+#include "lttng-ust-ctl.h"
+#include "lttng-ust-error.h"
#include "utils.h"
#include "ust-app.h"
#include "agent.h"
attr->attr.overwrite = !!ksession->snapshot_mode;
}
- /* Enforce mmap output for snapshot sessions. */
- if (ksession->snapshot_mode) {
- attr->attr.output = LTTNG_EVENT_MMAP;
- }
-
/* Validate common channel properties. */
if (channel_validate(attr) < 0) {
ret = LTTNG_ERR_INVALID;
DBG3("Channel %s already enabled. Skipping", uchan->name);
ret = LTTNG_ERR_UST_CHAN_EXIST;
goto end;
+ } else {
+ uchan->enabled = 1;
+ DBG2("Channel %s enabled successfully", uchan->name);
+ }
+
+ if (!usess->active) {
+ /*
+ * The channel will be activated against the apps
+ * when the session is started as part of the
+ * application channel "synchronize" operation.
+ */
+ goto end;
}
DBG2("Channel %s being enabled in UST domain", uchan->name);
*/
(void) ust_app_enable_channel_glb(usess, uchan);
- uchan->enabled = 1;
- DBG2("Channel %s enabled successfully", uchan->name);
end:
return ret;
struct ltt_ust_channel *uchan = NULL;
struct lttng_channel *defattr = NULL;
enum lttng_domain_type domain = LTTNG_DOMAIN_UST;
+ bool chan_published = false;
assert(usess);
/*
* Invalid subbuffer size if it's lower then the page size.
*/
- if (attr->attr.subbuf_size < page_size) {
+ if (attr->attr.subbuf_size < the_page_size) {
ret = LTTNG_ERR_INVALID;
goto error;
}
goto error_free_chan;
}
- /* Enable channel for global domain */
- ret = ust_app_create_channel_glb(usess, uchan);
- if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
- ret = LTTNG_ERR_UST_CHAN_FAIL;
- 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))) {
lttng_ht_add_unique_str(usess->domain_global.channels, &uchan->node);
+ chan_published = true;
} else {
/*
* Copy channel attribute to session if this is metadata so if NO
agt = agent_create(domain);
if (!agt) {
ret = LTTNG_ERR_NOMEM;
- goto error_free_chan;
+ goto error_remove_chan;
}
agent_add(agt, usess->agents);
}
channel_attr_destroy(defattr);
return LTTNG_OK;
+error_remove_chan:
+ if (chan_published) {
+ trace_ust_delete_channel(usess->domain_global.channels, uchan);
+ }
error_free_chan:
- /*
- * No need to remove the channel from the hash table because at this point
- * it was not added hence the direct call and no call_rcu().
- */
trace_ust_destroy_channel(uchan);
error:
channel_attr_destroy(defattr);
goto end;
}
+ uchan->enabled = 0;
+
+ /*
+ * If session is inactive we don't notify the tracer right away. We
+ * wait for the next synchronization.
+ */
+ if (!usess->active) {
+ goto end;
+ }
+
DBG2("Channel %s being disabled in UST global domain", uchan->name);
/* Disable channel for global domain */
ret = ust_app_disable_channel_glb(usess, uchan);
goto error;
}
- uchan->enabled = 0;
-
DBG2("Channel %s disabled successfully", uchan->name);
return LTTNG_OK;
error:
return ret;
}
+
+struct lttng_channel *trace_ust_channel_to_lttng_channel(
+ const struct ltt_ust_channel *uchan)
+{
+ struct lttng_channel *channel = NULL, *ret = NULL;
+
+ 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 = NULL;
+
+end:
+ lttng_channel_destroy(channel);
+ return ret;
+}