Fix: load event state (enabled/disabled) correctly
[lttng-tools.git] / src / common / config / session-config.c
index ba938d9f1578863b9253c28d61bbe7bd29b4ff08..743b5143893a4364cf5bf4f314e408102f77824d 100644 (file)
@@ -95,20 +95,23 @@ const char * const config_element_output_type = "output_type";
 const char * const config_element_tracefile_size = "tracefile_size";
 const char * const config_element_tracefile_count = "tracefile_count";
 const char * const config_element_live_timer_interval = "live_timer_interval";
+LTTNG_HIDDEN const char * const config_element_discarded_events = "discarded_events";
+LTTNG_HIDDEN const char * const config_element_lost_packets = "lost_packets";
 const char * const config_element_type = "type";
 const char * const config_element_buffer_type = "buffer_type";
 const char * const config_element_session = "session";
 const char * const config_element_sessions = "sessions";
-const char * const config_element_context_perf = "perf";
-const char * const config_element_context_app = "app";
-const char * const config_element_context_app_provider_name = "provider_name";
-const char * const config_element_context_app_ctx_name = "ctx_name";
+LTTNG_HIDDEN const char * const config_element_context_perf = "perf";
+LTTNG_HIDDEN const char * const config_element_context_app = "app";
+LTTNG_HIDDEN const char * const config_element_context_app_provider_name = "provider_name";
+LTTNG_HIDDEN const char * const config_element_context_app_ctx_name = "ctx_name";
 const char * const config_element_config = "config";
 const char * const config_element_started = "started";
 const char * const config_element_snapshot_mode = "snapshot_mode";
 const char * const config_element_loglevel = "loglevel";
 const char * const config_element_loglevel_type = "loglevel_type";
 const char * const config_element_filter = "filter";
+LTTNG_HIDDEN const char * const config_element_filter_expression = "filter_expression";
 const char * const config_element_snapshot_outputs = "snapshot_outputs";
 const char * const config_element_consumer_output = "consumer_output";
 const char * const config_element_destination = "destination";
@@ -168,8 +171,16 @@ const char * const config_event_context_pthread_id = "PTHREAD_ID";
 const char * const config_event_context_hostname = "HOSTNAME";
 const char * const config_event_context_ip = "IP";
 const char * const config_event_context_perf_thread_counter = "PERF_THREAD_COUNTER";
-const char * const config_event_context_app = "APP";
-
+LTTNG_HIDDEN const char * const config_event_context_app = "APP";
+LTTNG_HIDDEN const char * const config_event_context_interruptible = "INTERRUPTIBLE";
+LTTNG_HIDDEN const char * const config_event_context_preemptible = "PREEMPTIBLE";
+LTTNG_HIDDEN const char * const config_event_context_need_reschedule = "NEED_RESCHEDULE";
+LTTNG_HIDDEN const char * const config_event_context_migratable = "MIGRATABLE";
+
+enum process_event_node_phase {
+       CREATION = 0,
+       ENABLE = 1,
+};
 
 struct consumer_output {
        int enabled;
@@ -454,7 +465,40 @@ int config_writer_open_element(struct config_writer *writer,
        ret = xmlTextWriterStartElement(writer->writer, encoded_element_name);
        xmlFree(encoded_element_name);
 end:
-       return ret > 0 ? 0 : ret;
+       return ret >= 0 ? 0 : ret;
+}
+
+LTTNG_HIDDEN
+int config_writer_write_attribute(struct config_writer *writer,
+               const char *name, const char *value)
+{
+       int ret;
+       xmlChar *encoded_name = NULL;
+       xmlChar *encoded_value = NULL;
+
+       if (!writer || !writer->writer || !name || !name[0]) {
+               ret = -1;
+               goto end;
+       }
+
+       encoded_name = encode_string(name);
+       if (!encoded_name) {
+               ret = -1;
+               goto end;
+       }
+
+       encoded_value = encode_string(value);
+       if (!encoded_value) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = xmlTextWriterWriteAttribute(writer->writer, encoded_name,
+                       encoded_value);
+end:
+       xmlFree(encoded_name);
+       xmlFree(encoded_value);
+       return ret >= 0 ? 0 : ret;
 }
 
 LTTNG_HIDDEN
@@ -469,7 +513,7 @@ int config_writer_close_element(struct config_writer *writer)
 
        ret = xmlTextWriterEndElement(writer->writer);
 end:
-       return ret > 0 ? 0 : ret;
+       return ret >= 0 ? 0 : ret;
 }
 
 LTTNG_HIDDEN
@@ -494,7 +538,7 @@ int config_writer_write_element_unsigned_int(struct config_writer *writer,
                encoded_element_name, "%" PRIu64, value);
        xmlFree(encoded_element_name);
 end:
-       return ret > 0 ? 0 : ret;
+       return ret >= 0 ? 0 : ret;
 }
 
 LTTNG_HIDDEN
@@ -519,7 +563,7 @@ int config_writer_write_element_signed_int(struct config_writer *writer,
                encoded_element_name, "%" PRIi64, value);
        xmlFree(encoded_element_name);
 end:
-       return ret > 0 ? 0 : ret;
+       return ret >= 0 ? 0 : ret;
 }
 
 LTTNG_HIDDEN
@@ -561,7 +605,7 @@ int config_writer_write_element_string(struct config_writer *writer,
 end:
        xmlFree(encoded_element_name);
        xmlFree(encoded_value);
-       return ret > 0 ? 0 : ret;
+       return ret >= 0 ? 0 : ret;
 }
 
 static
@@ -951,6 +995,18 @@ int get_context_type(xmlChar *context_type)
        } else if (!strcmp((char *) context_type,
                config_event_context_ip)) {
                ret = LTTNG_EVENT_CONTEXT_IP;
+       } else if (!strcmp((char *) context_type,
+               config_event_context_interruptible)) {
+               ret = LTTNG_EVENT_CONTEXT_INTERRUPTIBLE;
+       } else if (!strcmp((char *) context_type,
+               config_event_context_preemptible)) {
+               ret = LTTNG_EVENT_CONTEXT_PREEMPTIBLE;
+       } else if (!strcmp((char *) context_type,
+               config_event_context_need_reschedule)) {
+               ret = LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE;
+       } else if (!strcmp((char *) context_type,
+               config_event_context_migratable)) {
+               ret = LTTNG_EVENT_CONTEXT_MIGRATABLE;
        } else {
                goto error;
        }
@@ -1100,17 +1156,16 @@ end:
 }
 
 static
-int create_session_net_output(const char *name, struct lttng_domain *domain,
-       const char *control_uri, const char *data_uri)
+int create_session_net_output(const char *name, const char *control_uri,
+               const char *data_uri)
 {
        int ret;
        struct lttng_handle *handle;
        const char *uri = NULL;
 
        assert(name);
-       assert(domain);
 
-       handle = lttng_create_handle(name, domain);
+       handle = lttng_create_handle(name, NULL);
        if (!handle) {
                ret = -LTTNG_ERR_NOMEM;
                goto end;
@@ -1292,11 +1347,6 @@ int create_session(const char *name,
        }
 
        if (output.control_uri || output.data_uri) {
-               int i;
-               struct lttng_domain *domain;
-               struct lttng_domain *domains[] =
-                       { kernel_domain, ust_domain, jul_domain, log4j_domain };
-
                /* network destination */
                if (live_timer_interval && live_timer_interval != UINT64_MAX) {
                        /*
@@ -1312,18 +1362,12 @@ int create_session(const char *name,
                        goto end;
                }
 
-               for (i = 0; i < (sizeof(domains) / sizeof(domains[0])); i++) {
-                       domain = domains[i];
-                       if (!domain) {
-                               continue;
-                       }
-
-                       ret = create_session_net_output(name, domain, output.control_uri,
-                                       output.data_uri);
-                       if (ret) {
-                               goto end;
-                       }
+               ret = create_session_net_output(name, output.control_uri,
+                               output.data_uri);
+               if (ret) {
+                       goto end;
                }
+
        } else {
                /* either local output or no output */
                ret = lttng_create_session(name, output.path);
@@ -1416,9 +1460,9 @@ end:
 
 static
 int process_event_node(xmlNodePtr event_node, struct lttng_handle *handle,
-       const char *channel_name)
+       const char *channel_name, const enum process_event_node_phase phase)
 {
-       int ret, i;
+       int ret = 0, i;
        xmlNodePtr node;
        struct lttng_event event;
        char **exclusions = NULL;
@@ -1669,25 +1713,14 @@ int process_event_node(xmlNodePtr event_node, struct lttng_handle *handle,
                }
        }
 
-       ret = lttng_enable_event_with_exclusions(handle, &event, channel_name,
-                       filter_expression, exclusion_count, exclusions);
-       if (ret) {
-               goto end;
-       }
-
-       if (!event.enabled) {
-               /*
-                * Note that we should use lttng_disable_event_ext() (2.6+) to
-                * eliminate the risk of clashing on events of the same
-                * name (with different event types and loglevels).
-                *
-                * Unfortunately, lttng_disable_event_ext() only performs a
-                * match on the name and event type and errors out if any other
-                * event attribute is not set to its default value.
-                *
-                * This will disable all events that match this name.
-                */
-               ret = lttng_disable_event(handle, event.name, channel_name);
+       if ((event.enabled && phase == ENABLE) || phase == CREATION) {
+               ret = lttng_enable_event_with_exclusions(handle, &event, channel_name,
+                               filter_expression, exclusion_count, exclusions);
+               if (ret < 0) {
+                       WARN("Enabling event (name:%s) on load failed.", event.name);
+                       ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+                       goto end;
+               }
        }
 end:
        for (i = 0; i < exclusion_count; i++) {
@@ -1704,6 +1737,7 @@ int process_events_node(xmlNodePtr events_node, struct lttng_handle *handle,
        const char *channel_name)
 {
        int ret = 0;
+       struct lttng_event event;
        xmlNodePtr node;
 
        assert(events_node);
@@ -1712,11 +1746,33 @@ int process_events_node(xmlNodePtr events_node, struct lttng_handle *handle,
 
        for (node = xmlFirstElementChild(events_node); node;
                node = xmlNextElementSibling(node)) {
-               ret = process_event_node(node, handle, channel_name);
+               ret = process_event_node(node, handle, channel_name, CREATION);
                if (ret) {
                        goto end;
                }
        }
+
+       /*
+        * Disable all events to enable only the necessary events.
+        * Limitations regarding lttng_disable_events and tuple descriptor
+        * force this approach.
+        */
+       memset(&event, 0, sizeof(event));
+       event.loglevel = -1;
+       event.type = LTTNG_EVENT_ALL;
+       ret = lttng_disable_event_ext(handle, &event, channel_name, NULL);
+       if (ret) {
+               goto end;
+       }
+
+       for (node = xmlFirstElementChild(events_node); node;
+                       node = xmlNextElementSibling(node)) {
+               ret = process_event_node(node, handle, channel_name, ENABLE);
+               if (ret) {
+                       goto end;
+               }
+       }
+
 end:
        return ret;
 }
This page took 0.027032 seconds and 4 git commands to generate.