X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng-sessiond%2Fchannel.c;h=3dc04ccb83829ad2077dc2ced938d3ee6c40671b;hp=14fdfdcae0050038ab6ad26fd14fe991425eaa1e;hb=58f3ca76ddd0d871fc1b71d816bdbabe1d7adeb1;hpb=9df8df5ea4a12be72f265c3c0d6911ac4e207bc0 diff --git a/lttng-sessiond/channel.c b/lttng-sessiond/channel.c index 14fdfdcae..3dc04ccb8 100644 --- a/lttng-sessiond/channel.c +++ b/lttng-sessiond/channel.c @@ -15,18 +15,20 @@ * Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define _GNU_SOURCE #include #include #include +#include #include #include #include "channel.h" -#include "hashtable.h" -#include "kernel-ctl.h" +#include "kernel.h" #include "ust-ctl.h" #include "utils.h" +#include "ust-app.h" /* * Return allocated channel attributes. @@ -37,13 +39,13 @@ struct lttng_channel *channel_new_default_attr(int dom) chan = zmalloc(sizeof(struct lttng_channel)); if (chan == NULL) { - perror("malloc channel init"); + PERROR("zmalloc channel init"); goto error_alloc; } if (snprintf(chan->name, sizeof(chan->name), "%s", DEFAULT_CHANNEL_NAME) < 0) { - perror("snprintf default channel name"); + PERROR("snprintf default channel name"); goto error; } @@ -52,19 +54,19 @@ struct lttng_channel *channel_new_default_attr(int dom) chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; switch (dom) { - case LTTNG_DOMAIN_KERNEL: - chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; - chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; - chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; - break; - case LTTNG_DOMAIN_UST: - case LTTNG_DOMAIN_UST_PID: - chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; - chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; - chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; - break; - default: - goto error; /* Not implemented */ + case LTTNG_DOMAIN_KERNEL: + chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; + chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; + break; + case LTTNG_DOMAIN_UST: + case LTTNG_DOMAIN_UST_PID: + chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; + chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; + break; + default: + goto error; /* Not implemented */ } return chan; @@ -75,37 +77,6 @@ error_alloc: return NULL; } -/* - * Copy two ltt ust channel. Dst and src must be already allocated. - */ -int channel_ust_copy(struct ltt_ust_channel *dst, - struct ltt_ust_channel *src) -{ - //struct ltt_ust_event *uevent, *new_uevent; - - memcpy(dst, src, sizeof(struct ltt_ust_channel)); - dst->events = hashtable_new_str(0); - - /* - cds_list_for_each_entry(uevent, &src->events.head, list) { - new_uevent = malloc(sizeof(struct ltt_ust_event)); - if (new_uevent == NULL) { - perror("malloc ltt_ust_event"); - goto error; - } - - memcpy(new_uevent, uevent, sizeof(struct ltt_ust_event)); - cds_list_add(&new_uevent->list, &dst->events.head); - dst->events.count++; - } - */ - - return 0; - -//error: -// return -1; -} - /* * Disable kernel channel of the kernel session. */ @@ -121,10 +92,8 @@ int channel_kernel_disable(struct ltt_kernel_session *ksession, goto error; } else if (kchan->enabled == 1) { ret = kernel_disable_channel(kchan); - if (ret < 0) { - if (ret != EEXIST) { - ret = LTTCOMM_KERN_CHAN_DISABLE_FAIL; - } + if (ret < 0 && ret != -EEXIST) { + ret = LTTCOMM_KERN_CHAN_DISABLE_FAIL; goto error; } } @@ -161,19 +130,19 @@ error: * Create kernel channel of the kernel session and notify kernel thread. */ int channel_kernel_create(struct ltt_kernel_session *ksession, - struct lttng_channel *chan, int kernel_pipe) + struct lttng_channel *attr, int kernel_pipe) { int ret; - struct lttng_channel *attr = chan; + struct lttng_channel *defattr = NULL; /* Creating channel attributes if needed */ if (attr == NULL) { - /* FIXME: this appears to be a memory leak */ - attr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL); - if (attr == NULL) { + defattr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL); + if (defattr == NULL) { ret = LTTCOMM_FATAL; goto error; } + attr = defattr; } /* Channel not found, creating it */ @@ -191,119 +160,165 @@ int channel_kernel_create(struct ltt_kernel_session *ksession, } ret = LTTCOMM_OK; - error: + free(defattr); return ret; } /* - * Create UST channel and enable it on the tracer. + * Enable UST channel for session and domain. */ -int channel_ust_create(struct ltt_ust_session *usess, - struct lttng_channel *attr) +int channel_ust_enable(struct ltt_ust_session *usess, int domain, + struct ltt_ust_channel *uchan) { - int ret; - struct ltt_ust_channel *uchan; - //struct lttng_ust_channel_attr uattr; - //struct object_data *obj; + int ret = LTTCOMM_OK; - uchan = trace_ust_find_channel_by_name(usess->domain_global.channels, - attr->name); - if (uchan == NULL) { - uchan = trace_ust_create_channel(attr, usess->pathname); - if (uchan == NULL) { - ret = LTTCOMM_UST_CHAN_FAIL; - goto error; - } - rcu_read_lock(); - hashtable_add_unique(usess->domain_global.channels, &uchan->node); - rcu_read_unlock(); - } else { - ret = LTTCOMM_UST_CHAN_EXIST; - goto error; + /* If already enabled, everything is OK */ + if (uchan->enabled) { + DBG3("Channel %s already enabled. Skipping", uchan->name); + goto end; } - /* TODO: NOTIFY ust application to update */ - /* - ret = ustctl_create_channel(sock, usession->handle, &uattr, &obj); - if (ret < 0) { - ret = LTTCOMM_UST_CHAN_FAIL; + switch (domain) { + case LTTNG_DOMAIN_UST: + DBG2("Channel %s being enabled in UST global domain", uchan->name); + /* Enable channel for global domain */ + ret = ust_app_enable_channel_glb(usess, uchan); + break; + case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: + case LTTNG_DOMAIN_UST_EXEC_NAME: + ret = LTTCOMM_NOT_IMPLEMENTED; goto error; } - */ - /* - uchan->attr.overwrite = uattr.overwrite; - uchan->attr.subbuf_size = uattr.subbuf_size; - uchan->attr.num_subbuf = uattr.num_subbuf; - uchan->attr.switch_timer_interval = uattr.switch_timer_interval; - uchan->attr.read_timer_interval = uattr.read_timer_interval; - uchan->attr.output = uattr.output; - uchan->handle = obj->handle; - uchan->attr.shm_fd = obj->shm_fd; - uchan->attr.wait_fd = obj->wait_fd; - uchan->attr.memory_map_size = obj->memory_map_size; - uchan->obj = obj; - */ - - /* Add channel to session */ - //rcu_read_lock(); - //cds_list_add(&uchan->list, &usession->channels.head); - //usession->channels.count++; - //rcu_read_unlock(); - - //DBG2("Channel %s UST create successfully for sock:%d", uchan->name, sock); + if (ret < 0) { + if (ret != -EEXIST) { + ret = LTTCOMM_UST_CHAN_ENABLE_FAIL; + goto error; + } else { + ret = LTTCOMM_OK; + } + } - ret = LTTCOMM_OK; + uchan->enabled = 1; + DBG2("Channel %s enabled successfully", uchan->name); +end: error: return ret; } /* - * Enable UST channel on the tracer. + * Create UST channel for session and domain. */ -int channel_ust_enable(struct ltt_ust_session *usession, - struct ltt_ust_channel *uchan, int sock) +int channel_ust_create(struct ltt_ust_session *usess, int domain, + struct lttng_channel *attr) { int ret = LTTCOMM_OK; -#ifdef DISABLE - struct object_data obj; + struct lttng_ht *chan_ht; + struct ltt_ust_channel *uchan = NULL; + struct lttng_channel *defattr = NULL; - obj.shm_fd = uchan->attr.shm_fd; - obj.wait_fd = uchan->attr.wait_fd; - obj.memory_map_size = uchan->attr.memory_map_size; - ret = ustctl_enable(sock, &obj); - if (ret < 0) { - ret = LTTCOMM_UST_CHAN_FAIL; - goto end; + /* Creating channel attributes if needed */ + if (attr == NULL) { + defattr = channel_new_default_attr(domain); + if (defattr == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + attr = defattr; } - ret = LTTCOMM_OK; -end: -#endif + + /* Create UST channel */ + uchan = trace_ust_create_channel(attr, usess->pathname); + if (uchan == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } + uchan->enabled = 1; + + switch (domain) { + case LTTNG_DOMAIN_UST: + DBG2("Channel %s being created in UST global domain", uchan->name); + + /* Adding the channel to the channel hash table. */ + rcu_read_lock(); + lttng_ht_add_unique_str(usess->domain_global.channels, &uchan->node); + rcu_read_unlock(); + + /* Enable channel for global domain */ + ret = ust_app_create_channel_glb(usess, uchan); + break; + case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: + case LTTNG_DOMAIN_UST_EXEC_NAME: + default: + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error_free_chan; + } + + if (ret < 0 && ret != -EEXIST) { + ret = LTTCOMM_UST_CHAN_ENABLE_FAIL; + goto error_free_chan; + } + + DBG2("Channel %s created successfully", uchan->name); + + free(defattr); + return LTTCOMM_OK; + +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: + free(defattr); return ret; } /* - * Disable UST channel on the tracer. + * Disable UST channel for session and domain. */ -int channel_ust_disable(struct ltt_ust_session *usession, - struct ltt_ust_channel *uchan, int sock) +int channel_ust_disable(struct ltt_ust_session *usess, int domain, + struct ltt_ust_channel *uchan) { int ret = LTTCOMM_OK; -#ifdef DISABLE - struct object_data obj; - obj.shm_fd = uchan->attr.shm_fd; - obj.wait_fd = uchan->attr.wait_fd; - obj.memory_map_size = uchan->attr.memory_map_size; - ret = ustctl_disable(sock, &obj); - if (ret < 0) { - ret = LTTCOMM_UST_CHAN_FAIL; + /* Already disabled */ + if (uchan->enabled == 0) { + DBG2("Channel UST %s already disabled", uchan->name); goto end; } - ret = LTTCOMM_OK; + + /* Get the right channel's hashtable */ + switch (domain) { + case LTTNG_DOMAIN_UST: + DBG2("Channel %s being disabled in UST global domain", uchan->name); + /* Disable channel for global domain */ + ret = ust_app_disable_channel_glb(usess, uchan); + break; + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: + case LTTNG_DOMAIN_UST_EXEC_NAME: + case LTTNG_DOMAIN_UST_PID: + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; + } + + if (ret < 0 && ret != -EEXIST) { + ret = LTTCOMM_UST_DISABLE_FAIL; + goto error; + } + + uchan->enabled = 0; + + DBG2("Channel %s disabled successfully", uchan->name); + + return LTTCOMM_OK; + end: -#endif +error: return ret; }