+ if (ust_chan->domain == LTTNG_DOMAIN_UST) {
+ ret = save_ust_events(writer, ust_chan->events);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ } else {
+ struct agent *agent = NULL;
+
+ agent = trace_ust_find_agent(session, ust_chan->domain);
+ if (!agent) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ ERR("Could not find agent associated to UST subdomain");
+ goto end;
+ }
+
+ /*
+ * Channels associated with a UST sub-domain (such as JUL, Log4j
+ * or Python) don't have any non-internal events. We retrieve
+ * the "agent" events associated with this channel and serialize
+ * them.
+ */
+ ret = save_agent_events(writer, agent);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ }
+
+ ret = save_ust_context(writer, &ust_chan->ctx_list);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+
+ /* /channel */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ ret = LTTNG_OK;
+end:
+ return ret;
+}
+
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
+static
+int save_kernel_session(struct config_writer *writer,
+ struct ltt_session *session)
+{
+ int ret;
+ struct ltt_kernel_channel *kchan;
+
+ assert(writer);
+ assert(session);
+
+ ret = config_writer_write_element_string(writer, config_element_type,
+ config_domain_type_kernel);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ 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;