Fix: channel_ust_create: remove channel on agent error
[lttng-tools.git] / src / bin / lttng-sessiond / channel.c
index 8a88eccedb62ab788835468f56f193ce86d9b8fc..f19dbec37f51697209c0ae1d678a1af7768e8533 100644 (file)
@@ -72,6 +72,7 @@ struct lttng_channel *channel_new_default_attr(int dom,
                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;
                break;
@@ -97,6 +98,7 @@ common_ust:
                                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;
                        break;
@@ -111,6 +113,7 @@ common_ust:
                                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;
                        break;
@@ -217,6 +220,15 @@ static int channel_validate(struct lttng_channel *attr)
        return 0;
 }
 
+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) {
+               return -1;
+       }
+       return 0;
+}
+
 /*
  * Create kernel channel of the kernel session and notify kernel thread.
  */
@@ -258,6 +270,11 @@ int channel_kernel_create(struct ltt_kernel_session *ksession,
                goto error;
        }
 
+       if (channel_validate_kernel(attr) < 0) {
+               ret = LTTNG_ERR_INVALID;
+               goto error;
+       }
+
        /* Channel not found, creating it */
        ret = kernel_create_channel(ksession, attr);
        if (ret < 0) {
@@ -325,6 +342,7 @@ int channel_ust_create(struct ltt_ust_session *usess,
        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);
 
@@ -459,6 +477,7 @@ int channel_ust_create(struct ltt_ust_session *usess,
        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
@@ -478,7 +497,7 @@ int channel_ust_create(struct ltt_ust_session *usess,
                        agt = agent_create(domain);
                        if (!agt) {
                                ret = LTTNG_ERR_NOMEM;
-                               goto error_free_chan;
+                               goto error_remove_chan;
                        }
                        agent_add(agt, usess->agents);
                }
@@ -487,11 +506,11 @@ int channel_ust_create(struct ltt_ust_session *usess,
        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);
This page took 0.025558 seconds and 5 git commands to generate.