Add session-config api for array and element manipulation
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Thu, 23 Jun 2016 21:08:49 +0000 (17:08 -0400)
committerJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Mon, 11 Jul 2016 15:20:32 +0000 (11:20 -0400)
src/common/config/session-config.c
src/common/config/session-config.h

index 56ba2c4fe4c92da0765223511f2d01ce2f65d785..1c8a1e3ed5ffce1383b90c64c3f115151ce42415 100644 (file)
@@ -3757,3 +3757,446 @@ void config_element_free(struct config_element *element) {
 
        free(element);
 }
+
+LTTNG_HIDDEN
+void config_element_free_array(struct config_element **array, int size) {
+
+       if (array) {
+               for (int i = 0; i < size; i++) {
+                       if (!array[i]) {
+                               continue;
+                       }
+                       if (array[i]->element) {
+                               xmlFreeNode(array[i]->element);
+                       }
+                       free(array[i]);
+               }
+       }
+       free(array);
+}
+
+LTTNG_HIDDEN
+void config_document_get_element_array(const struct config_document *document, const char *xpath, struct config_element ***element_array, int *array_size)
+{
+       int xpath_result_size;
+
+       xmlXPathContextPtr xpath_context = NULL;
+       xmlXPathObjectPtr xpath_object = NULL;
+       xmlNodeSetPtr xpath_result_set = NULL;
+       xmlChar *internal_xpath = NULL;
+       xmlChar *internal_value = NULL;
+
+       assert(document);
+       assert(xpath);
+
+       *element_array=NULL;
+       *array_size=0;
+
+
+       internal_xpath = encode_string(xpath);
+       if (!internal_xpath) {
+               ERR("Unable to encode xpath string");
+               goto end;
+       }
+
+       /* Initialize xpath context */
+       xpath_context = xmlXPathNewContext(document->document);
+       if (!xpath_context) {
+               ERR("Unable to create xpath context");
+               goto end;
+       }
+
+       /* Evaluate the xpath expression */
+       xpath_object = xmlXPathEvalExpression(internal_xpath, xpath_context);
+       if (!xpath_object) {
+               ERR("Unable to evaluate xpath query (invalid query format)");
+               goto end;
+       }
+
+       xpath_result_set = xpath_object->nodesetval;
+       if (!xpath_result_set) {
+               goto end;
+       }
+
+       xpath_result_size = xpath_result_set->nodeNr;
+
+       if (xpath_result_size == 0) {
+               goto end;
+       }
+
+       /* alloc the array */
+       *element_array = calloc(xpath_result_size, sizeof(struct config_element *));
+       *array_size = xpath_result_size;
+       if (!element_array) {
+               ERR("Calloc config element array");
+               goto end;
+       }
+
+       for (int i = 0; i < xpath_result_size; i++) {
+               xmlNodePtr node_copy = NULL;
+               node_copy = xmlCopyNode(xpath_result_set->nodeTab[i], 1);
+               if (!node_copy) {
+                       ERR("Xml copy of event node");
+                       goto error;
+               }
+               /* Hand off ownership */
+               (*element_array)[i] = malloc(sizeof(struct config_element));
+               if (!((*element_array)[i])){
+                       ERR("Malloc config_element array");
+                       xmlFreeNode(node_copy);
+                       goto error;
+               };
+               (*element_array)[i]->element = node_copy;
+       }
+end:
+       xmlXPathFreeContext(xpath_context);
+       xmlXPathFreeObject(xpath_object);
+       xmlFree(internal_xpath);
+       xmlFree(internal_value);
+       return;
+error:
+
+       if (element_array) {
+               config_element_free_array(*element_array, *array_size);
+       }
+
+       *array_size = 0;
+
+       xmlXPathFreeContext(xpath_context);
+       xmlXPathFreeObject(xpath_object);
+       xmlFree(internal_xpath);
+       xmlFree(internal_value);
+       return;
+}
+
+LTTNG_HIDDEN
+void config_element_get_element_array(const struct config_element *element, const char *xpath, struct config_element ***element_array, int *array_size)
+{
+       int xpath_result_size;
+
+       xmlXPathContextPtr xpath_context = NULL;
+       xmlXPathObjectPtr xpath_object = NULL;
+       xmlNodeSetPtr xpath_result_set = NULL;
+       xmlChar *internal_xpath = NULL;
+       xmlChar *internal_value = NULL;
+       xmlNodePtr local_copy = NULL;
+       xmlNodePtr place_holder = NULL;
+       xmlDocPtr document = NULL;
+
+       assert(element);
+       assert(element->element);
+       assert(xpath);
+
+       *element_array=NULL;
+       *array_size=0;
+
+       /* Create a new doc and set root node as passed element */
+       document = xmlNewDoc(BAD_CAST "1.0");
+       if (!document) {
+               ERR("Unable to create xml document");
+               goto end;
+       }
+
+       local_copy = xmlCopyNode(element->element, 1);
+       if (!local_copy) {
+               ERR("Unable to copy an xml node");
+               goto end;
+       }
+
+       /* Hand off the local_copy to the xmlDoc */
+       place_holder = xmlDocSetRootElement(document, local_copy);
+       if (place_holder) {
+               ERR("The document root was already set");
+               xmlFreeNode(local_copy);
+               goto end;
+       }
+
+       internal_xpath = encode_string(xpath);
+       if (!internal_xpath) {
+               ERR("Unable to encode xpath string");
+               goto end;
+       }
+
+       /* Initialize xpath context */
+       xpath_context = xmlXPathNewContext(document);
+       if (!xpath_context) {
+               ERR("Unable to create xpath context");
+               goto end;
+       }
+
+       /* Evaluate the xpath expression */
+       xpath_object = xmlXPathEvalExpression(internal_xpath, xpath_context);
+       if (!xpath_object) {
+               ERR("Unable to evaluate xpath query (invalid query format)");
+               goto end;
+       }
+
+       xpath_result_set = xpath_object->nodesetval;
+       if (!xpath_result_set) {
+               goto end;
+       }
+
+       xpath_result_size = xpath_result_set->nodeNr;
+
+       if (xpath_result_size == 0) {
+               goto end;
+       }
+
+       /* alloc the array */
+       *element_array = calloc(xpath_result_size, sizeof(struct config_element *));
+       *array_size = xpath_result_size;
+       if (!element_array) {
+               ERR("Calloc config element array");
+               goto end;
+       }
+
+       for (int i = 0; i < xpath_result_size; i++) {
+               xmlNodePtr node_copy = NULL;
+               node_copy = xmlCopyNode(xpath_result_set->nodeTab[i], 1);
+               if (!node_copy) {
+                       ERR("Xml copy of event node");
+                       goto error;
+               }
+               /* Hand off ownership */
+               (*element_array)[i] = malloc(sizeof(struct config_element));
+               if (!((*element_array)[i])){
+                       ERR("Malloc config_element array");
+                       xmlFreeNode(node_copy);
+                       goto error;
+               };
+               (*element_array)[i]->element = node_copy;
+       }
+end:
+       xmlXPathFreeContext(xpath_context);
+       xmlXPathFreeObject(xpath_object);
+       xmlFree(internal_xpath);
+       xmlFree(internal_value);
+       xmlFreeDoc(document);
+       return;
+error:
+
+       if (element_array) {
+               config_element_free_array(*element_array, *array_size);
+       }
+
+       *array_size = 0;
+
+       xmlXPathFreeContext(xpath_context);
+       xmlXPathFreeObject(xpath_object);
+       xmlFree(internal_xpath);
+       xmlFree(internal_value);
+       return;
+}
+/* Create an internal copy of the config_element.
+ * The users is responsible for the freeing of the passed child.
+ */
+LTTNG_HIDDEN
+int config_element_add_or_replace_child(struct config_element *parent, struct config_element *child)
+{
+       assert(parent);
+       assert(child);
+       assert(parent->element);
+       assert(child->element);
+
+       int ret = 0;
+       xmlNodePtr local_copy;
+       xmlNodePtr x_ret = NULL;
+       xmlNodePtr iterator = NULL;
+
+       xmlNodePtr x_parent = parent->element;
+       xmlNodePtr x_child = child->element;
+
+       /* Find and delete the node with the same name if present */
+       iterator = x_parent->children;
+       while (iterator != NULL) {
+               if ((!xmlStrcmp(iterator->name, x_child->name))){
+                       xmlNodePtr del = iterator;
+                       iterator = iterator->next;
+                       xmlUnlinkNode(del);
+                       xmlFreeNode(del);
+               } else {
+                       iterator = iterator->next;
+               }
+       }
+
+       /* Add the child */
+       local_copy = xmlCopyNode(x_child, 1);
+       if (!local_copy) {
+               ret = -1;
+               ERR("Duplication of node to be insert failed");
+               goto end;
+       }
+       x_ret = xmlAddChild(x_parent, local_copy);
+       if (!x_ret) {
+               xmlFreeNode(local_copy);
+       }
+end:
+       return ret;
+}
+
+LTTNG_HIDDEN
+char *config_element_get_element_value(const struct config_element *element, const char *xpath)
+{
+       char *value = NULL;
+       int xpath_result_size;
+       int value_result_size;
+
+       xmlXPathContextPtr xpath_context = NULL;
+       xmlXPathObjectPtr xpath_object = NULL;
+       xmlNodeSetPtr xpath_result_set = NULL;
+       xmlChar *internal_xpath = NULL;
+       xmlChar *internal_value = NULL;
+       xmlDocPtr document = NULL;
+       xmlNodePtr local_copy = NULL;
+       xmlNodePtr place_holder = NULL;
+
+       assert(element);
+       assert(element->element);
+       assert(xpath);
+
+       /* Create a new doc and set root node as passed element */
+       document = xmlNewDoc(BAD_CAST "1.0");
+       if (!document) {
+               value = NULL;
+               ERR("Unable to create xml document");
+               goto end;
+       }
+
+       local_copy = xmlCopyNode(element->element, 1);
+       if (!local_copy) {
+               value = NULL;
+               ERR("Unable to copy an xml node");
+               goto end;
+       }
+
+       /* Hand off the local_copy to the xmlDoc */
+       place_holder = xmlDocSetRootElement(document, local_copy);
+       if (place_holder) {
+               value = NULL;
+               ERR("The document root was already set");
+               xmlFreeNode(local_copy);
+               goto end;
+       }
+
+       internal_xpath = encode_string(xpath);
+       if (!internal_xpath) {
+               /*TODO set valid error */
+               value = NULL;
+               ERR("Unable to encode xpath string");
+               goto end;
+       }
+
+       /* Initialize xpath context */
+       xpath_context = xmlXPathNewContext(document);
+       if (!xpath_context) {
+               /*TODO set valid error */
+               value = NULL;
+               ERR("Unable to create xpath context");
+               goto end;
+       }
+
+       /* Evaluate the xpath expression */
+       xpath_object = xmlXPathEvalExpression(internal_xpath, xpath_context);
+       if (!xpath_object) {
+               /*TODO set valid error */
+               value = NULL;
+               ERR("Unable to evaluate xpath query (invalid query format)");
+               goto end;
+       }
+
+       xpath_result_set = xpath_object->nodesetval;
+       if (!xpath_result_set) {
+               /*TODO set valid error */
+               value = NULL;
+               goto end;
+       }
+
+       xpath_result_size = xpath_result_set->nodeNr;
+
+       if (xpath_result_size > 1) {
+               /*TODO set valid error */
+               ERR("To many result while fetching config element value");
+               value = NULL;
+               goto end;
+       }
+
+       if (xpath_result_size == 0) {
+               value = NULL;
+               goto end;
+       }
+
+       assert(xpath_result_set->nodeTab[0]);
+       internal_value = xmlNodeGetContent(xpath_result_set->nodeTab[0]);
+       if (!internal_value) {
+               value = NULL;
+               goto end;
+       }
+
+       value_result_size  = xmlStrlen(internal_value);
+       value = calloc(value_result_size + 1, sizeof(char));
+       strncpy(value, (char *) internal_value, value_result_size);
+
+end:
+       xmlXPathFreeContext(xpath_context);
+       xmlXPathFreeObject(xpath_object);
+       xmlFree(internal_xpath);
+       xmlFree(internal_value);
+       xmlFreeDoc(document);
+       return value;
+
+}
+
+LTTNG_HIDDEN
+int config_process_event_element(const struct config_element *element, const char *session_name, int domain_type, const char *channel_name) {
+
+       int ret = 0;
+       xmlNodePtr node;
+       struct lttng_domain domain;
+       struct lttng_handle *handle;
+
+       assert(element);
+       assert(element->element);
+
+       memset(&domain, 0, sizeof(struct lttng_domain));
+
+       /* Create handle */
+       domain.type = domain_type;
+       switch (domain.type) {
+       case LTTNG_DOMAIN_KERNEL:
+               domain.buf_type = LTTNG_BUFFER_GLOBAL;
+               break;
+       case LTTNG_DOMAIN_UST:
+       case LTTNG_DOMAIN_JUL:
+       case LTTNG_DOMAIN_LOG4J:
+       case LTTNG_DOMAIN_PYTHON:
+               domain.buf_type = LTTNG_BUFFER_PER_UID;
+               break;
+       case LTTNG_DOMAIN_NONE:
+       default:
+               assert(0);
+       }
+
+       handle = lttng_create_handle(session_name, &domain);
+       if (!handle) {
+               ERR("Handle creation");
+               ret = 1;
+               goto error;
+       }
+
+
+       node = element->element;
+       /* Check if element is really and event */
+       if (xmlStrcmp(BAD_CAST config_element_event, node->name)) {
+               ERR("Passed element is not an event");
+               ret = 1;
+               goto error;
+       }
+
+       ret = process_event_node(node, handle, channel_name, ENABLE);
+       if (ret) {
+               goto error;
+       }
+error:
+       free(handle);
+       return ret;
+}
index b6a42483ae523c988401d526be814b9bdde4d13c..c29d40af46d0592155d31398d1eff601e00c67cd 100644 (file)
@@ -38,6 +38,7 @@ struct config_writer;
 /* Instance of a configuration document */
 struct config_document;
 
+/* Instance of a configuration element */
 struct config_element;
 
 /*
@@ -353,13 +354,26 @@ LTTNG_HIDDEN
 int config_document_element_exist(struct config_document *document, const char *xpath);
 
 /*
+ * Create a configuration element.
  *
+ * name The name of the element
+ * value The value to be assigned to the element. The value can be NULL.
+ *
+ * Returns a new configuration element.
+ *
+ * The caller is responsible of freeing the allocated element with
+ * config_element_free.
  */
 LTTNG_HIDDEN
-void config_element_free(struct config_element *element);
+struct config_element *config_element_create(const char *name, const char *value);
 
+/*
+ * Free a config_element
+ *
+ * element The element to free.
+ */
 LTTNG_HIDDEN
-struct config_element *config_element_create(const char *name, const char *value);
+void config_element_free(struct config_element *element);
 
 /*
  * Add a child element to an element.
@@ -386,5 +400,86 @@ int config_element_add_child(struct config_element *parent, const struct config_
 LTTNG_HIDDEN
 int config_document_insert_element(struct config_document *document, const char *xpath, const struct config_element *element);
 
+/*
+ * Get an array of elements from a document.
+ *
+ * document The source document.
+ * xpath The xpath string matching the elements path.
+ * element_array The resulting array
+ * array_size The resulting array size
+ *
+ * element_array is NULL on error.
+ *
+ * The caller is responsible of freeing the array with
+ * config_element_free_array.
+ */
+LTTNG_HIDDEN
+void config_document_get_element_array(const struct config_document *document, const char *xpath, struct config_element ***element_array, int *array_size);
+
+/*
+ * Get an array of elements from an element.
+ *
+ * element The source element.
+ * xpath The xpath string matching the elements path.
+ * element_array The resulting array
+ * array_size The resulting array size
+ *
+ * element_array is NULL on error.
+ *
+ * The caller is responsible of freeing the array with
+ * config_element_free_array.
+ */
+LTTNG_HIDDEN
+void config_element_get_element_array(const struct config_element *element, const char *xpath, struct config_element ***element_array, int *array_size);
+
+/*
+ * Free an array of element.
+ *
+ * array The array to free
+ * size The size of the array
+ */
+LTTNG_HIDDEN
+void config_element_free_array(struct config_element **array, int size);
+
+/*
+ * Add an element as a child if a equivalent element is present replace it with
+ * the passed element.
+ *
+ * parent The parent element.
+ * child The child to add.
+ *
+ * Returns zero if the session could be loaded successfully. Returns
+ * a negative LTTNG_ERR code on error.
+ */
+LTTNG_HIDDEN
+int config_element_add_or_replace_child(struct config_element *parent, struct config_element *child);
+
+/*
+ * Get the value of an element under an element.
+ *
+ * element The base element.
+ * xpath The xpath string to the element.
+ *
+ * Return null if multiple values exists or there is no
+ * value for the passed path.
+ */
+LTTNG_HIDDEN
+char *config_element_get_element_value(const struct config_element *element, const char *xpath);
+
+/*
+ * Process an element matching an event configuration and try to enable it.
+ *
+ * element The element to process
+ * session_name The session name to use for event enabling.
+ * domain_type The domain type to use for event enabling
+ * channel_name The channel name to use for event enabling
+ *              A NULL channel name will default to the default domain
+ *              channel.
+ *
+ * Returns zero if the session could be loaded successfully. Returns
+ * a negative LTTNG_ERR code on error.
+ */
+LTTNG_HIDDEN
+int config_process_event_element(const struct config_element *element, const char* session_name, int domain_type, const char *channel_name);
 
 #endif /* _CONFIG_H */
This page took 0.033347 seconds and 5 git commands to generate.