+ ret = config_writer_write_element_string(writer,
+ config_element_buffer_type, config_buffer_type_global);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ ret = config_writer_open_element(writer,
+ config_element_channels);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head,
+ list) {
+ ret = save_kernel_channel(writer, kchan);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ }
+
+ /* /channels */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ ret = LTTNG_OK;
+end:
+ return ret;
+}
+
+static
+const char *get_config_domain_str(enum lttng_domain_type domain)
+{
+ const char *str_dom;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ str_dom = config_domain_type_kernel;
+ break;
+ case LTTNG_DOMAIN_UST:
+ str_dom = config_domain_type_ust;
+ break;
+ case LTTNG_DOMAIN_JUL:
+ str_dom = config_domain_type_jul;
+ break;
+ case LTTNG_DOMAIN_LOG4J:
+ str_dom = config_domain_type_log4j;
+ break;
+ case LTTNG_DOMAIN_PYTHON:
+ str_dom = config_domain_type_python;
+ break;
+ default:
+ assert(0);
+ }
+
+ return str_dom;
+}
+
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
+static int save_id_tracker(struct config_writer *writer,
+ struct ltt_session *sess,
+ int domain,
+ enum lttng_tracker_type tracker_type)
+{
+ int ret = LTTNG_OK;
+ unsigned int nr_ids, i;
+ struct lttng_tracker_ids *ids = NULL;
+ const char *element_id_tracker, *element_target_id, *element_id;
+ const struct lttng_tracker_id *id;
+ enum lttng_tracker_id_status status;
+ int value;
+ const char *string;
+
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ element_id_tracker = config_element_pid_tracker;
+ element_target_id = config_element_target_pid;
+ element_id = config_element_pid;
+ break;
+ case LTTNG_TRACKER_VPID:
+ element_id_tracker = config_element_vpid_tracker;
+ element_target_id = config_element_target_vpid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_UID:
+ element_id_tracker = config_element_uid_tracker;
+ element_target_id = config_element_target_uid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_VUID:
+ element_id_tracker = config_element_vuid_tracker;
+ element_target_id = config_element_target_vuid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_GID:
+ element_id_tracker = config_element_gid_tracker;
+ element_target_id = config_element_target_gid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_VGID:
+ element_id_tracker = config_element_vgid_tracker;
+ element_target_id = config_element_target_vgid;
+ element_id = config_element_id;
+ break;
+ default:
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ {
+ ret = kernel_list_tracker_ids(
+ tracker_type, sess->kernel_session, &ids);
+ if (ret != LTTNG_OK) {
+ ret = LTTNG_ERR_KERN_LIST_FAIL;
+ goto end;
+ }
+ break;
+ }
+ case LTTNG_DOMAIN_UST:
+ {
+ ret = trace_ust_list_tracker_ids(
+ tracker_type, sess->ust_session, &ids);
+ if (ret != LTTNG_OK) {
+ ret = LTTNG_ERR_UST_LIST_FAIL;
+ goto end;
+ }
+ break;
+ }
+ case LTTNG_DOMAIN_JUL:
+ case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_PYTHON:
+ default:
+ ret = LTTNG_ERR_UNKNOWN_DOMAIN;
+ goto end;
+ }
+
+ status = lttng_tracker_ids_get_count(ids, &nr_ids);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ if (nr_ids == 1) {
+ id = lttng_tracker_ids_get_at_index(ids, 0);
+ if (id && lttng_tracker_id_get_type(id) == LTTNG_ID_ALL) {
+ /* Tracking all, nothing to output. */
+ ret = LTTNG_OK;
+ goto end;
+ }
+ }
+
+ ret = config_writer_open_element(writer, element_id_tracker);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ ret = config_writer_open_element(writer, config_element_targets);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ if (nr_ids == 0) {
+ /* Tracking none: empty list. */
+ ret = config_writer_open_element(writer, element_target_id);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ /* /$element_target_id */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ } else {
+ /* Tracking list. */
+ for (i = 0; i < nr_ids; i++) {
+ id = lttng_tracker_ids_get_at_index(ids, i);
+ if (!id) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ switch (lttng_tracker_id_get_type(id)) {
+ case LTTNG_ID_VALUE:
+ ret = config_writer_open_element(
+ writer, element_target_id);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ status = lttng_tracker_id_get_value(id, &value);
+ ret = config_writer_write_element_unsigned_int(
+ writer, element_id, value);
+ break;
+ case LTTNG_ID_STRING:
+ ret = config_writer_open_element(
+ writer, element_target_id);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ status = lttng_tracker_id_get_string(
+ id, &string);
+ ret = config_writer_write_element_string(writer,
+ config_element_name, string);
+ break;
+ default:
+ /* Unexpected. */
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ /* /$element_target_id */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ }