Fix: Memory allocated by xmlNodeGetContent() must be freed by xmlFree()
[lttng-tools.git] / src / common / config / config.c
index bfb2576f4d5bab954b37958d7c1d672bcbfd7c13..a4b59ff0865e559e3f2dea86bbc8c3cc022bcec2 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #define _GNU_SOURCE
+#define _LGPL_SOURCE
 #include <assert.h>
 #include <ctype.h>
 #include <stdio.h>
@@ -31,6 +32,7 @@
 #include <common/error.h>
 #include <common/macros.h>
 #include <common/utils.h>
+#include <common/compat/getenv.h>
 #include <lttng/lttng-error.h>
 #include <libxml/parser.h>
 #include <libxml/valid.h>
@@ -113,10 +115,15 @@ const char * const config_element_net_output = "net_output";
 const char * const config_element_control_uri = "control_uri";
 const char * const config_element_data_uri = "data_uri";
 const char * const config_element_max_size = "max_size";
+const char * const config_element_pid = "pid";
+const char * const config_element_pids = "pids";
+const char * const config_element_shared_memory_path = "shared_memory_path";
 
 const char * const config_domain_type_kernel = "KERNEL";
 const char * const config_domain_type_ust = "UST";
 const char * const config_domain_type_jul = "JUL";
+const char * const config_domain_type_log4j = "LOG4J";
+const char * const config_domain_type_python = "PYTHON";
 
 const char * const config_buffer_type_per_pid = "PER_PID";
 const char * const config_buffer_type_per_uid = "PER_UID";
@@ -353,7 +360,7 @@ end:
 }
 
 LTTNG_HIDDEN
-struct config_writer *config_writer_create(int fd_output)
+struct config_writer *config_writer_create(int fd_output, int indent)
 {
        int ret;
        struct config_writer *writer;
@@ -379,12 +386,12 @@ struct config_writer *config_writer_create(int fd_output)
 
        ret = xmlTextWriterSetIndentString(writer->writer,
                BAD_CAST config_xml_indent_string);
-       if (ret)  {
+       if (ret) {
                goto error_destroy;
        }
 
-       ret = xmlTextWriterSetIndent(writer->writer, 1);
-       if (ret)  {
+       ret = xmlTextWriterSetIndent(writer->writer, indent);
+       if (ret) {
                goto error_destroy;
        }
 
@@ -592,7 +599,7 @@ static
 char *get_session_config_xsd_path()
 {
        char *xsd_path;
-       const char *base_path = getenv(DEFAULT_SESSION_CONFIG_XSD_PATH_ENV);
+       const char *base_path = lttng_secure_getenv(DEFAULT_SESSION_CONFIG_XSD_PATH_ENV);
        size_t base_path_len;
        size_t max_path_len;
 
@@ -749,6 +756,10 @@ int get_domain_type(xmlChar *domain)
                ret = LTTNG_DOMAIN_UST;
        } else if (!strcmp((char *) domain, config_domain_type_jul)) {
                ret = LTTNG_DOMAIN_JUL;
+       } else if (!strcmp((char *) domain, config_domain_type_log4j)) {
+               ret = LTTNG_DOMAIN_LOG4J;
+       } else if (!strcmp((char *) domain, config_domain_type_python)) {
+               ret = LTTNG_DOMAIN_PYTHON;
        } else {
                goto error;
        }
@@ -1236,6 +1247,7 @@ int create_session(const char *name,
        struct lttng_domain *kernel_domain,
        struct lttng_domain *ust_domain,
        struct lttng_domain *jul_domain,
+       struct lttng_domain *log4j_domain,
        xmlNodePtr output_node,
        uint64_t live_timer_interval)
 {
@@ -1276,7 +1288,7 @@ int create_session(const char *name,
                int i;
                struct lttng_domain *domain;
                struct lttng_domain *domains[] =
-                       { kernel_domain, ust_domain, jul_domain };
+                       { kernel_domain, ust_domain, jul_domain, log4j_domain };
 
                /* network destination */
                if (live_timer_interval && live_timer_interval != UINT64_MAX) {
@@ -1632,6 +1644,24 @@ 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);
+       }
 end:
        for (i = 0; i < exclusion_count; i++) {
                free(exclusions[i]);
@@ -1956,7 +1986,9 @@ int process_context_node(xmlNodePtr context_node,
                xmlNodePtr perf_attr_node;
 
                /* perf */
-               context.ctx = LTTNG_EVENT_CONTEXT_PERF_COUNTER;
+               context.ctx = handle->domain.type == LTTNG_DOMAIN_KERNEL ?
+                       LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER :
+                       LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER;
                for (perf_attr_node = xmlFirstElementChild(context_child_node);
                        perf_attr_node; perf_attr_node =
                                xmlNextElementSibling(perf_attr_node)) {
@@ -2140,13 +2172,16 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
 {
        int ret, started = -1, snapshot_mode = -1;
        uint64_t live_timer_interval = UINT64_MAX;
-       char *name = NULL;
+       xmlChar *name = NULL;
+       xmlChar *shm_path = NULL;
        xmlNodePtr domains_node = NULL;
        xmlNodePtr output_node = NULL;
        xmlNodePtr node;
        struct lttng_domain *kernel_domain = NULL;
        struct lttng_domain *ust_domain = NULL;
        struct lttng_domain *jul_domain = NULL;
+       struct lttng_domain *log4j_domain = NULL;
+       struct lttng_domain *python_domain = NULL;
 
        for (node = xmlFirstElementChild(session_node); node;
                node = xmlNextElementSibling(node)) {
@@ -2159,7 +2194,7 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
                                goto error;
                        }
 
-                       name = (char *) node_content;
+                       name = node_content;
                } else if (!domains_node && !strcmp((const char *) node->name,
                        config_element_domains)) {
                        /* domains */
@@ -2183,6 +2218,16 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
                        config_element_output)) {
                        /* output */
                        output_node = node;
+               } else if (!shm_path && !strcmp((const char *) node->name,
+                       config_element_shared_memory_path)) {
+                       /* shared memory path */
+                       xmlChar *node_content = xmlNodeGetContent(node);
+                       if (!node_content) {
+                               ret = -LTTNG_ERR_NOMEM;
+                               goto error;
+                       }
+
+                       shm_path = node_content;
                } else {
                        /* attributes, snapshot_mode or live_timer_interval */
                        xmlNodePtr attributes_child =
@@ -2229,7 +2274,7 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
                goto error;
        }
 
-       if (session_name && strcmp(name, session_name)) {
+       if (session_name && strcmp((char *) name, session_name)) {
                /* This is not the session we are looking for */
                ret = -LTTNG_ERR_NO_SESSION;
                goto error;
@@ -2273,6 +2318,20 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
                        }
                        jul_domain = domain;
                        break;
+               case LTTNG_DOMAIN_LOG4J:
+                       if (log4j_domain) {
+                               /* Same domain seen twice, invalid! */
+                               goto domain_init_error;
+                       }
+                       log4j_domain = domain;
+                       break;
+               case LTTNG_DOMAIN_PYTHON:
+                       if (python_domain) {
+                               /* Same domain seen twice, invalid! */
+                               goto domain_init_error;
+                       }
+                       python_domain = domain;
+                       break;
                default:
                        WARN("Invalid domain type");
                        goto domain_init_error;
@@ -2286,7 +2345,7 @@ domain_init_error:
 
        if (override) {
                /* Destroy session if it exists */
-               ret = lttng_destroy_session(name);
+               ret = lttng_destroy_session((const char *) name);
                if (ret && ret != -LTTNG_ERR_SESS_NOT_FOUND) {
                        ERR("Failed to destroy existing session.");
                        goto error;
@@ -2295,30 +2354,40 @@ domain_init_error:
 
        /* Create session type depending on output type */
        if (snapshot_mode && snapshot_mode != -1) {
-               ret = create_snapshot_session(name, output_node);
+               ret = create_snapshot_session((const char *) name, output_node);
        } else if (live_timer_interval &&
                live_timer_interval != UINT64_MAX) {
-               ret = create_session(name, kernel_domain, ust_domain, jul_domain,
+               ret = create_session((const char *) name, kernel_domain,
+                               ust_domain, jul_domain, log4j_domain,
                                output_node, live_timer_interval);
        } else {
                /* regular session */
-               ret = create_session(name, kernel_domain, ust_domain, jul_domain,
+               ret = create_session((const char *) name, kernel_domain,
+                               ust_domain, jul_domain, log4j_domain,
                                output_node, UINT64_MAX);
        }
        if (ret) {
                goto error;
        }
 
+       if (shm_path) {
+               ret = lttng_set_session_shm_path((const char *) name,
+                               (const char *) shm_path);
+               if (ret) {
+                       goto error;
+               }
+       }
+
        for (node = xmlFirstElementChild(domains_node); node;
                node = xmlNextElementSibling(node)) {
-               ret = process_domain_node(node, name);
+               ret = process_domain_node(node, (const char *) name);
                if (ret) {
                        goto end;
                }
        }
 
        if (started) {
-               ret = lttng_start_tracing(name);
+               ret = lttng_start_tracing((const char *) name);
                if (ret) {
                        goto end;
                }
@@ -2326,15 +2395,19 @@ domain_init_error:
 
 end:
        if (ret < 0) {
-               ERR("Failed to load session %s: %s", name, lttng_strerror(ret));
-               lttng_destroy_session(name);
+               ERR("Failed to load session %s: %s", (const char *) name,
+                       lttng_strerror(ret));
+               lttng_destroy_session((const char *) name);
        }
 
 error:
        free(kernel_domain);
        free(ust_domain);
        free(jul_domain);
-       free(name);
+       free(log4j_domain);
+       free(python_domain);
+       xmlFree(name);
+       xmlFree(shm_path);
        return ret;
 }
 
This page took 0.026842 seconds and 4 git commands to generate.