+ lttng_process_attr_tracker_handle_destroy(tracker_handle);
+ return ret;
+ }
+
+static int process_id_tracker_node(xmlNodePtr id_tracker_node,
+ struct lttng_handle *handle,
+ enum lttng_process_attr process_attr)
+{
+ int ret = 0, child_count;
+ xmlNodePtr values_node = NULL;
+ xmlNodePtr node;
+ const char *element_id_tracker;
+ const char *element_target_id;
+ const char *element_id;
+ const char *element_id_alias;
+ const char *element_name;
+ enum lttng_error_code tracker_handle_ret_code;
+ struct lttng_process_attr_tracker_handle *tracker_handle = NULL;
+ enum lttng_process_attr_tracker_handle_status status;
+
+ assert(handle);
+ assert(id_tracker_node);
+
+ tracker_handle_ret_code = lttng_session_get_tracker_handle(
+ handle->session_name, handle->domain.type, process_attr,
+ &tracker_handle);
+ if (tracker_handle_ret_code != LTTNG_OK) {
+ ret = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ ret = get_tracker_elements(process_attr, &element_id_tracker,
+ &element_target_id, &element_id, &element_id_alias,
+ &element_name);
+ if (ret) {
+ goto end;
+ }
+
+ /* get the values node */
+ for (node = xmlFirstElementChild(id_tracker_node); node;
+ node = xmlNextElementSibling(node)) {
+ if (!strcmp((const char *) node->name,
+ config_element_process_attr_values)) {
+ values_node = node;
+ break;
+ }
+ }
+
+ if (!values_node) {
+ ret = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ /* Go through all id target node */
+ child_count = xmlChildElementCount(values_node);
+ status = lttng_process_attr_tracker_handle_set_tracking_policy(
+ tracker_handle,
+ child_count == 0 ? LTTNG_TRACKING_POLICY_EXCLUDE_ALL :
+ LTTNG_TRACKING_POLICY_INCLUDE_SET);
+ if (status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
+ ret = LTTNG_ERR_UNK;
+ goto end;
+ }
+
+ /* Add all tracked values. */
+ for (node = xmlFirstElementChild(values_node); node;
+ node = xmlNextElementSibling(node)) {
+ xmlNodePtr id_target_node = node;
+
+ /* get id node and track it */
+ for (node = xmlFirstElementChild(id_target_node); node;
+ node = xmlNextElementSibling(node)) {
+ if (!strcmp((const char *) node->name, element_id) ||
+ (element_id_alias &&
+ !strcmp((const char *) node->name,
+ element_id_alias))) {
+ int64_t id;
+ xmlChar *content = xmlNodeGetContent(node);
+
+ if (!content) {
+ ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
+ ret = parse_int(content, &id);
+ free(content);
+ if (ret) {
+ ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ status = lttng_process_attr_process_id_tracker_handle_add_pid(
+ tracker_handle,
+ (pid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ status = lttng_process_attr_virtual_process_id_tracker_handle_add_pid(
+ tracker_handle,
+ (pid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ status = lttng_process_attr_user_id_tracker_handle_add_uid(
+ tracker_handle,
+ (uid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ status = lttng_process_attr_virtual_user_id_tracker_handle_add_uid(
+ tracker_handle,
+ (uid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ status = lttng_process_attr_group_id_tracker_handle_add_gid(
+ tracker_handle,
+ (gid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ status = lttng_process_attr_virtual_group_id_tracker_handle_add_gid(
+ tracker_handle,
+ (gid_t) id);
+ break;
+ default:
+ ret = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ } else if (element_name &&
+ !strcmp((const char *) node->name,
+ element_name)) {
+ xmlChar *content = xmlNodeGetContent(node);
+
+ if (!content) {
+ ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ status = lttng_process_attr_user_id_tracker_handle_add_user_name(
+ tracker_handle,
+ (const char *) content);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ status = lttng_process_attr_virtual_user_id_tracker_handle_add_user_name(
+ tracker_handle,
+ (const char *) content);
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ status = lttng_process_attr_group_id_tracker_handle_add_group_name(
+ tracker_handle,
+ (const char *) content);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ status = lttng_process_attr_virtual_group_id_tracker_handle_add_group_name(
+ tracker_handle,
+ (const char *) content);
+ break;
+ default:
+ free(content);
+ ret = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ free(content);
+ }
+ switch (status) {
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
+ continue;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID:
+ ret = LTTNG_ERR_INVALID;
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS:
+ ret = LTTNG_ERR_PROCESS_ATTR_EXISTS;
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING:
+ ret = LTTNG_ERR_PROCESS_ATTR_MISSING;
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR:
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR:
+ default:
+ ret = LTTNG_ERR_UNK;
+ goto end;
+ }
+ }
+ node = id_target_node;
+ }
+
+end:
+ lttng_process_attr_tracker_handle_destroy(tracker_handle);