X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fsave.c;h=f01c3186bf313864952610fca304f559f3b9bc08;hp=8daf870c270395ab3675b6eb35a15db81c8f3168;hb=ac41e67e39946acd97752ce52b964976890c5e87;hpb=f829d17ad1141d0fb130edc1aa26d446ffed146b diff --git a/src/bin/lttng-sessiond/save.c b/src/bin/lttng-sessiond/save.c index 8daf870c2..f01c3186b 100644 --- a/src/bin/lttng-sessiond/save.c +++ b/src/bin/lttng-sessiond/save.c @@ -1,18 +1,8 @@ /* - * Copyright (C) 2014 - Jérémie Galarneau + * Copyright (C) 2014 Jérémie Galarneau * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License, version 2 only, as - * published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _LGPL_SOURCE @@ -36,6 +26,7 @@ #include "trace-ust.h" #include "agent.h" +/* Return LTTNG_OK on success else a LTTNG_ERR* code. */ static int save_kernel_channel_attributes(struct config_writer *writer, struct lttng_channel_attr *attr) @@ -47,12 +38,14 @@ int save_kernel_channel_attributes(struct config_writer *writer, attr->overwrite ? config_overwrite_mode_overwrite : config_overwrite_mode_discard); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } ret = config_writer_write_element_unsigned_int(writer, config_element_subbuf_size, attr->subbuf_size); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -60,6 +53,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_num_subbuf, attr->num_subbuf); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -67,6 +61,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_switch_timer_interval, attr->switch_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -74,6 +69,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_read_timer_interval, attr->read_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -82,12 +78,14 @@ int save_kernel_channel_attributes(struct config_writer *writer, attr->output == LTTNG_EVENT_SPLICE ? config_output_type_splice : config_output_type_mmap); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } ret = config_writer_write_element_unsigned_int(writer, config_element_tracefile_size, attr->tracefile_size); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -95,6 +93,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_tracefile_count, attr->tracefile_count); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -102,6 +101,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_live_timer_interval, attr->live_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -113,6 +113,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_monitor_timer_interval, ext->monitor_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -120,14 +121,17 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_blocking_timeout, ext->blocking_timeout); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } } + ret = LTTNG_OK; end: - return ret ? LTTNG_ERR_SAVE_IO_FAIL : 0; + return ret; } +/* Return LTTNG_OK on success else a LTTNG_ERR* code. */ static int save_ust_channel_attributes(struct config_writer *writer, struct lttng_ust_channel_attr *attr) @@ -140,12 +144,14 @@ int save_ust_channel_attributes(struct config_writer *writer, attr->overwrite ? config_overwrite_mode_overwrite : config_overwrite_mode_discard); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } ret = config_writer_write_element_unsigned_int(writer, config_element_subbuf_size, attr->subbuf_size); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -153,6 +159,7 @@ int save_ust_channel_attributes(struct config_writer *writer, config_element_num_subbuf, attr->num_subbuf); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -160,6 +167,7 @@ int save_ust_channel_attributes(struct config_writer *writer, config_element_switch_timer_interval, attr->switch_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -167,6 +175,7 @@ int save_ust_channel_attributes(struct config_writer *writer, config_element_read_timer_interval, attr->read_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -175,6 +184,7 @@ int save_ust_channel_attributes(struct config_writer *writer, attr->output == LTTNG_UST_MMAP ? config_output_type_mmap : config_output_type_splice); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -182,6 +192,7 @@ int save_ust_channel_attributes(struct config_writer *writer, config_element_blocking_timeout, attr->u.s.blocking_timeout); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -194,11 +205,13 @@ int save_ust_channel_attributes(struct config_writer *writer, config_element_monitor_timer_interval, channel->monitor_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } + ret = LTTNG_OK; end: - return ret ? LTTNG_ERR_SAVE_IO_FAIL : 0; + return ret; } static @@ -294,6 +307,63 @@ const char *get_kernel_context_type_string( case LTTNG_KERNEL_CONTEXT_CALLSTACK_KERNEL: context_type_string = config_event_context_callstack_kernel; break; + case LTTNG_KERNEL_CONTEXT_CGROUP_NS: + context_type_string = config_event_context_cgroup_ns; + break; + case LTTNG_KERNEL_CONTEXT_IPC_NS: + context_type_string = config_event_context_ipc_ns; + break; + case LTTNG_KERNEL_CONTEXT_MNT_NS: + context_type_string = config_event_context_mnt_ns; + break; + case LTTNG_KERNEL_CONTEXT_NET_NS: + context_type_string = config_event_context_net_ns; + break; + case LTTNG_KERNEL_CONTEXT_PID_NS: + context_type_string = config_event_context_pid_ns; + break; + case LTTNG_KERNEL_CONTEXT_USER_NS: + context_type_string = config_event_context_user_ns; + break; + case LTTNG_KERNEL_CONTEXT_UTS_NS: + context_type_string = config_event_context_uts_ns; + break; + case LTTNG_KERNEL_CONTEXT_UID: + context_type_string = config_event_context_uid; + break; + case LTTNG_KERNEL_CONTEXT_EUID: + context_type_string = config_event_context_euid; + break; + case LTTNG_KERNEL_CONTEXT_SUID: + context_type_string = config_event_context_suid; + break; + case LTTNG_KERNEL_CONTEXT_GID: + context_type_string = config_event_context_gid; + break; + case LTTNG_KERNEL_CONTEXT_EGID: + context_type_string = config_event_context_egid; + break; + case LTTNG_KERNEL_CONTEXT_SGID: + context_type_string = config_event_context_sgid; + break; + case LTTNG_KERNEL_CONTEXT_VUID: + context_type_string = config_event_context_vuid; + break; + case LTTNG_KERNEL_CONTEXT_VEUID: + context_type_string = config_event_context_veuid; + break; + case LTTNG_KERNEL_CONTEXT_VSUID: + context_type_string = config_event_context_vsuid; + break; + case LTTNG_KERNEL_CONTEXT_VGID: + context_type_string = config_event_context_vgid; + break; + case LTTNG_KERNEL_CONTEXT_VEGID: + context_type_string = config_event_context_vegid; + break; + case LTTNG_KERNEL_CONTEXT_VSGID: + context_type_string = config_event_context_vsgid; + break; default: context_type_string = NULL; } @@ -326,6 +396,45 @@ const char *get_ust_context_type_string( case LTTNG_UST_CONTEXT_APP_CONTEXT: context_type_string = config_event_context_app; break; + case LTTNG_UST_CONTEXT_CGROUP_NS: + context_type_string = config_event_context_cgroup_ns; + break; + case LTTNG_UST_CONTEXT_IPC_NS: + context_type_string = config_event_context_ipc_ns; + break; + case LTTNG_UST_CONTEXT_MNT_NS: + context_type_string = config_event_context_mnt_ns; + break; + case LTTNG_UST_CONTEXT_NET_NS: + context_type_string = config_event_context_net_ns; + break; + case LTTNG_UST_CONTEXT_PID_NS: + context_type_string = config_event_context_pid_ns; + break; + case LTTNG_UST_CONTEXT_USER_NS: + context_type_string = config_event_context_user_ns; + break; + case LTTNG_UST_CONTEXT_UTS_NS: + context_type_string = config_event_context_uts_ns; + break; + case LTTNG_UST_CONTEXT_VUID: + context_type_string = config_event_context_vuid; + break; + case LTTNG_UST_CONTEXT_VEUID: + context_type_string = config_event_context_veuid; + break; + case LTTNG_UST_CONTEXT_VSUID: + context_type_string = config_event_context_vsuid; + break; + case LTTNG_UST_CONTEXT_VGID: + context_type_string = config_event_context_vgid; + break; + case LTTNG_UST_CONTEXT_VEGID: + context_type_string = config_event_context_vegid; + break; + case LTTNG_UST_CONTEXT_VSGID: + context_type_string = config_event_context_vsgid; + break; case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER: /* * Error, should not be stored in the XML, perf contexts @@ -385,6 +494,7 @@ const char *get_loglevel_type_string( return loglevel_type_string; } +/* Return LTTNG_OK on success else a LTTNG_ERR* code. */ static int save_kernel_function_event(struct config_writer *writer, struct ltt_kernel_event *event) @@ -866,10 +976,13 @@ int save_kernel_event(struct config_writer *writer, 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_events(struct config_writer *writer, struct ltt_kernel_channel *kchan) @@ -885,7 +998,7 @@ int save_kernel_events(struct config_writer *writer, cds_list_for_each_entry(event, &kchan->events_list.head, list) { ret = save_kernel_event(writer, event); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } @@ -896,10 +1009,13 @@ int save_kernel_events(struct config_writer *writer, 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_ust_event(struct config_writer *writer, struct ltt_ust_event *event) @@ -1010,10 +1126,13 @@ int save_ust_event(struct config_writer *writer, 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_ust_events(struct config_writer *writer, struct lttng_ht *events) @@ -1038,7 +1157,7 @@ int save_ust_events(struct config_writer *writer, continue; } ret = save_ust_event(writer, event); - if (ret) { + if (ret != LTTNG_OK) { rcu_read_unlock(); goto end; } @@ -1051,22 +1170,25 @@ int save_ust_events(struct config_writer *writer, 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 init_ust_event_from_agent_event(struct ltt_ust_event *ust_event, struct agent_event *agent_event) { - int ret = 0; + int ret; enum lttng_ust_loglevel_type ust_loglevel_type; ust_event->enabled = agent_event->enabled; ust_event->attr.instrumentation = LTTNG_UST_TRACEPOINT; if (lttng_strncpy(ust_event->attr.name, agent_event->name, LTTNG_SYMBOL_NAME_LEN)) { - ret = -1; + ret = LTTNG_ERR_INVALID; goto end; } switch (agent_event->loglevel_type) { @@ -1081,7 +1203,7 @@ int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event, break; default: ERR("Invalid agent_event loglevel_type."); - ret = -1; + ret = LTTNG_ERR_INVALID; goto end; } @@ -1089,10 +1211,13 @@ int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event, ust_event->attr.loglevel = agent_event->loglevel_value; ust_event->filter_expression = agent_event->filter_expression; ust_event->exclusion = agent_event->exclusion; + + ret = LTTNG_OK; end: return ret; } +/* Return LTTNG_OK on success else a LTTNG_ERR* code. */ static int save_agent_events(struct config_writer *writer, struct agent *agent) @@ -1123,12 +1248,12 @@ int save_agent_events(struct config_writer *writer, * structures...). */ ret = init_ust_event_from_agent_event(&fake_event, agent_event); - if (ret) { + if (ret != LTTNG_OK) { rcu_read_unlock(); goto end; } ret = save_ust_event(writer, &fake_event); - if (ret) { + if (ret != LTTNG_OK) { rcu_read_unlock(); goto end; } @@ -1141,15 +1266,18 @@ int save_agent_events(struct config_writer *writer, 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_context(struct config_writer *writer, struct lttng_kernel_context *ctx) { - int ret = 0; + int ret = LTTNG_OK; if (!ctx) { goto end; @@ -1221,10 +1349,12 @@ int save_kernel_context(struct config_writer *writer, goto end; } + ret = LTTNG_OK; end: return ret; } +/* Return LTTNG_OK on success else a LTTNG_ERR* code. */ static int save_kernel_contexts(struct config_writer *writer, struct ltt_kernel_channel *kchan) @@ -1233,7 +1363,7 @@ int save_kernel_contexts(struct config_writer *writer, struct ltt_kernel_context *ctx; if (cds_list_empty(&kchan->ctx_list)) { - ret = 0; + ret = LTTNG_OK; goto end; } @@ -1245,7 +1375,7 @@ int save_kernel_contexts(struct config_writer *writer, cds_list_for_each_entry(ctx, &kchan->ctx_list, list) { ret = save_kernel_context(writer, &ctx->ctx); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } @@ -1256,10 +1386,13 @@ int save_kernel_contexts(struct config_writer *writer, 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_ust_context_perf_thread_counter(struct config_writer *writer, struct ltt_ust_context *ctx) @@ -1303,10 +1436,13 @@ int save_ust_context_perf_thread_counter(struct config_writer *writer, 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_ust_context_app_ctx(struct config_writer *writer, struct ltt_ust_context *ctx) @@ -1345,10 +1481,13 @@ int save_ust_context_app_ctx(struct config_writer *writer, 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_ust_context_generic(struct config_writer *writer, struct ltt_ust_context *ctx) @@ -1374,10 +1513,13 @@ int save_ust_context_generic(struct config_writer *writer, 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_ust_context(struct config_writer *writer, struct cds_list_head *ctx_list) @@ -1413,7 +1555,7 @@ int save_ust_context(struct config_writer *writer, /* Save generic context. */ ret = save_ust_context_generic(writer, ctx); } - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -1431,10 +1573,13 @@ int save_ust_context(struct config_writer *writer, 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_channel(struct config_writer *writer, struct ltt_kernel_channel *kchan) @@ -1465,17 +1610,17 @@ int save_kernel_channel(struct config_writer *writer, } ret = save_kernel_channel_attributes(writer, &kchan->channel->attr); - if (ret) { + if (ret != LTTNG_OK) { goto end; } ret = save_kernel_events(writer, kchan); - if (ret) { + if (ret != LTTNG_OK) { goto end; } ret = save_kernel_contexts(writer, kchan); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -1485,10 +1630,13 @@ int save_kernel_channel(struct config_writer *writer, 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_ust_channel(struct config_writer *writer, struct ltt_ust_channel *ust_chan, @@ -1521,7 +1669,7 @@ int save_ust_channel(struct config_writer *writer, } ret = save_ust_channel_attributes(writer, &ust_chan->attr); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -1549,7 +1697,7 @@ int save_ust_channel(struct config_writer *writer, if (ust_chan->domain == LTTNG_DOMAIN_UST) { ret = save_ust_events(writer, ust_chan->events); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } else { @@ -1569,13 +1717,13 @@ int save_ust_channel(struct config_writer *writer, * them. */ ret = save_agent_events(writer, agent); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } ret = save_ust_context(writer, &ust_chan->ctx_list); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -1585,10 +1733,13 @@ int save_ust_channel(struct config_writer *writer, 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) @@ -1623,7 +1774,7 @@ int save_kernel_session(struct config_writer *writer, cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head, list) { ret = save_kernel_channel(writer, kchan); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } @@ -1634,6 +1785,8 @@ int save_kernel_session(struct config_writer *writer, ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } + + ret = LTTNG_OK; end: return ret; } @@ -1666,19 +1819,63 @@ const char *get_config_domain_str(enum lttng_domain_type domain) return str_dom; } -static -int save_pid_tracker(struct config_writer *writer, - struct ltt_session *sess, int domain) +/* 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 = 0; - ssize_t nr_pids = 0, i; - int32_t *pids = NULL; + 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: { - nr_pids = kernel_list_tracker_pids(sess->kernel_session, &pids); - if (nr_pids < 0) { + ret = kernel_list_tracker_ids( + tracker_type, sess->kernel_session, &ids); + if (ret != LTTNG_OK) { ret = LTTNG_ERR_KERN_LIST_FAIL; goto end; } @@ -1686,8 +1883,9 @@ int save_pid_tracker(struct config_writer *writer, } case LTTNG_DOMAIN_UST: { - nr_pids = trace_ust_list_tracker_pids(sess->ust_session, &pids); - if (nr_pids < 0) { + ret = trace_ust_list_tracker_ids( + tracker_type, sess->ust_session, &ids); + if (ret != LTTNG_OK) { ret = LTTNG_ERR_UST_LIST_FAIL; goto end; } @@ -1701,64 +1899,168 @@ int save_pid_tracker(struct config_writer *writer, goto end; } - /* Only create a pid_tracker if enabled or untrack all */ - if (nr_pids != 1 || (nr_pids == 1 && pids[0] != -1)) { - ret = config_writer_open_element(writer, - config_element_pid_tracker); + 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; } - ret = config_writer_open_element(writer, - config_element_targets); + /* /$element_target_id */ + ret = config_writer_close_element(writer); if (ret) { ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } - - for (i = 0; i < nr_pids; i++) { - ret = config_writer_open_element(writer, - config_element_target_pid); - if (ret) { + } 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; } - - ret = config_writer_write_element_unsigned_int(writer, - config_element_pid, pids[i]); 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; + } - /* /pid_target */ + /* /$element_target_id */ ret = config_writer_close_element(writer); if (ret) { ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } } + } - /* /targets */ - ret = config_writer_close_element(writer); - if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; - goto end; - } + /* /targets */ + ret = config_writer_close_element(writer); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } - /* /pid_tracker */ - ret = config_writer_close_element(writer); - if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; - goto end; - } + /* /$element_id_tracker */ + ret = config_writer_close_element(writer); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; } + + ret = LTTNG_OK; end: - free(pids); + lttng_tracker_ids_destroy(ids); return ret; } +/* Return LTTNG_OK on success else a LTTNG_ERR* code. */ +static int save_id_trackers(struct config_writer *writer, + struct ltt_session *sess, + int domain) +{ + int ret; + + switch (domain) { + case LTTNG_DOMAIN_KERNEL: + ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_PID); + if (ret != LTTNG_OK) + return ret; + ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VPID); + if (ret != LTTNG_OK) + return ret; + ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_UID); + if (ret != LTTNG_OK) + return ret; + ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VUID); + if (ret != LTTNG_OK) + return ret; + ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_GID); + if (ret != LTTNG_OK) + return ret; + ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VGID); + if (ret != LTTNG_OK) + return ret; + break; + case LTTNG_DOMAIN_UST: + ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VPID); + if (ret != LTTNG_OK) + return ret; + ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VUID); + if (ret != LTTNG_OK) + return ret; + ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VGID); + if (ret != LTTNG_OK) + return ret; + break; + default: + return LTTNG_ERR_INVALID; + } + return LTTNG_OK; +} + +/* Return LTTNG_OK on success else a LTTNG_ERR* code. */ static int save_ust_domain(struct config_writer *writer, struct ltt_session *session, enum lttng_domain_type domain) @@ -1820,7 +2122,7 @@ int save_ust_domain(struct config_writer *writer, ust_chan = caa_container_of(node, struct ltt_ust_channel, node); if (domain == ust_chan->domain) { ret = save_ust_channel(writer, ust_chan, session->ust_session); - if (ret) { + if (ret != LTTNG_OK) { rcu_read_unlock(); goto end; } @@ -1843,14 +2145,15 @@ int save_ust_domain(struct config_writer *writer, goto end; } - ret = save_pid_tracker(writer, session, LTTNG_DOMAIN_UST); - if (ret) { + ret = save_id_trackers(writer, session, LTTNG_DOMAIN_UST); + if (ret != LTTNG_OK) { goto end; } /* /trackers */ ret = config_writer_close_element(writer); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } } @@ -1862,14 +2165,16 @@ int save_ust_domain(struct config_writer *writer, goto end; } + ret = LTTNG_OK; end: return ret; } +/* Return LTTNG_OK on success else a LTTNG_ERR* code. */ static int save_domains(struct config_writer *writer, struct ltt_session *session) { - int ret = 0; + int ret = LTTNG_OK; assert(writer); assert(session); @@ -1884,7 +2189,6 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) goto end; } - if (session->kernel_session) { ret = config_writer_open_element(writer, config_element_domain); @@ -1894,7 +2198,7 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) } ret = save_kernel_session(writer, session); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -1905,8 +2209,8 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) goto end; } - ret = save_pid_tracker(writer, session, LTTNG_DOMAIN_KERNEL); - if (ret) { + ret = save_id_trackers(writer, session, LTTNG_DOMAIN_KERNEL); + if (ret != LTTNG_OK) { goto end; } @@ -1926,22 +2230,22 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) if (session->ust_session) { ret = save_ust_domain(writer, session, LTTNG_DOMAIN_UST); - if (ret) { + if (ret != LTTNG_OK) { goto end; } ret = save_ust_domain(writer, session, LTTNG_DOMAIN_JUL); - if (ret) { + if (ret != LTTNG_OK) { goto end; } ret = save_ust_domain(writer, session, LTTNG_DOMAIN_LOG4J); - if (ret) { + if (ret != LTTNG_OK) { goto end; } ret = save_ust_domain(writer, session, LTTNG_DOMAIN_PYTHON); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } @@ -1952,10 +2256,13 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) 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_consumer_output(struct config_writer *writer, struct consumer_output *output) @@ -2036,10 +2343,10 @@ int save_consumer_output(struct config_writer *writer, ret = LTTNG_ERR_SAVE_IO_FAIL; goto end_net_output; } - + ret = LTTNG_OK; end_net_output: free(uri); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } else { @@ -2076,10 +2383,13 @@ end_net_output: 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_snapshot_outputs(struct config_writer *writer, struct snapshot *snapshot) @@ -2122,7 +2432,7 @@ int save_snapshot_outputs(struct config_writer *writer, } ret = save_consumer_output(writer, output->consumer); - if (ret) { + if (ret != LTTNG_OK) { goto end_unlock; } @@ -2142,6 +2452,7 @@ int save_snapshot_outputs(struct config_writer *writer, goto end; } + ret = LTTNG_OK; end: return ret; end_unlock: @@ -2149,6 +2460,7 @@ end_unlock: return ret; } +/* Return LTTNG_OK on success else a LTTNG_ERR* code. */ static int save_session_output(struct config_writer *writer, struct ltt_session *session) @@ -2161,7 +2473,7 @@ int save_session_output(struct config_writer *writer, if ((session->snapshot_mode && session->snapshot.nb_output == 0) || (!session->snapshot_mode && !session->consumer)) { /* Session is in no output mode */ - ret = 0; + ret = LTTNG_OK; goto end; } @@ -2173,13 +2485,13 @@ int save_session_output(struct config_writer *writer, if (session->snapshot_mode) { ret = save_snapshot_outputs(writer, &session->snapshot); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } else { if (session->consumer) { ret = save_consumer_output(writer, session->consumer); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } @@ -2191,6 +2503,7 @@ int save_session_output(struct config_writer *writer, ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } + ret = LTTNG_OK; end: return ret; } @@ -2278,19 +2591,19 @@ end: /* * Save the given session. * - * Return 0 on success else a LTTNG_ERR* code. + * Return LTTNG_OK on success else a LTTNG_ERR* code. */ static int save_session(struct ltt_session *session, struct lttng_save_session_attr *attr, lttng_sock_cred *creds) { - int ret, fd; - unsigned int file_opened = 0; /* Indicate if the file has been opened */ - char config_file_path[PATH_MAX]; + int ret, fd = -1; + char config_file_path[LTTNG_PATH_MAX]; size_t len; struct config_writer *writer = NULL; size_t session_name_len; const char *provided_path; + int file_open_flags = O_CREAT | O_WRONLY | O_TRUNC; assert(session); assert(attr); @@ -2301,7 +2614,7 @@ int save_session(struct ltt_session *session, if (!session_access_ok(session, LTTNG_SOCK_GET_UID_CRED(creds), - LTTNG_SOCK_GET_GID_CRED(creds))) { + LTTNG_SOCK_GET_GID_CRED(creds)) || session->destroyed) { ret = LTTNG_ERR_EPERM; goto end; } @@ -2314,7 +2627,7 @@ int save_session(struct ltt_session *session, ret = LTTNG_ERR_SET_URL; goto end; } - strncpy(config_file_path, provided_path, len); + strncpy(config_file_path, provided_path, sizeof(config_file_path)); } else { ssize_t ret_len; char *home_dir = utils_get_user_home_dir( @@ -2358,27 +2671,34 @@ int save_session(struct ltt_session *session, * was done just above. */ config_file_path[len++] = '/'; - strncpy(config_file_path + len, session->name, session_name_len); + strncpy(config_file_path + len, session->name, sizeof(config_file_path) - len); len += session_name_len; strcpy(config_file_path + len, DEFAULT_SESSION_CONFIG_FILE_EXTENSION); len += sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION); config_file_path[len] = '\0'; - if (!access(config_file_path, F_OK) && !attr->overwrite) { - /* File exists, notify the user since the overwrite flag is off. */ - ret = LTTNG_ERR_SAVE_FILE_EXIST; - goto end; + if (!attr->overwrite) { + file_open_flags |= O_EXCL; } - fd = run_as_open(config_file_path, O_CREAT | O_WRONLY | O_TRUNC, + fd = run_as_open(config_file_path, file_open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, LTTNG_SOCK_GET_UID_CRED(creds), LTTNG_SOCK_GET_GID_CRED(creds)); if (fd < 0) { PERROR("Could not create configuration file"); - ret = LTTNG_ERR_SAVE_IO_FAIL; + switch (errno) { + case EEXIST: + ret = LTTNG_ERR_SAVE_FILE_EXIST; + break; + case EACCES: + ret = LTTNG_ERR_EPERM; + break; + default: + ret = LTTNG_ERR_SAVE_IO_FAIL; + break; + } goto end; } - file_opened = 1; writer = config_writer_create(fd, 1); if (!writer) { @@ -2405,7 +2725,7 @@ int save_session(struct ltt_session *session, goto end; } - if(session->shm_path[0] != '\0') { + if (session->shm_path[0] != '\0') { ret = config_writer_write_element_string(writer, config_element_shared_memory_path, session->shm_path); @@ -2416,7 +2736,7 @@ int save_session(struct ltt_session *session, } ret = save_domains(writer, session); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -2468,7 +2788,7 @@ int save_session(struct ltt_session *session, } ret = save_session_output(writer, session); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -2485,21 +2805,25 @@ int save_session(struct ltt_session *session, ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } + + ret = LTTNG_OK; end: if (writer && config_writer_destroy(writer)) { /* Preserve the original error code */ - ret = ret ? ret : LTTNG_ERR_SAVE_IO_FAIL; + ret = ret != LTTNG_OK ? ret : LTTNG_ERR_SAVE_IO_FAIL; } - if (ret) { + if (ret != LTTNG_OK) { /* Delete file in case of error */ - if (file_opened && unlink(config_file_path)) { + if ((fd >= 0) && unlink(config_file_path)) { PERROR("Unlinking XML session configuration."); } } - if (file_opened) { - ret = close(fd); - if (ret) { + if (fd >= 0) { + int closeret; + + closeret = close(fd); + if (closeret) { PERROR("Closing XML session configuration"); } } @@ -2527,19 +2851,23 @@ int cmd_save_sessions(struct lttng_save_session_attr *attr, session_lock(session); ret = save_session(session, attr, creds); session_unlock(session); - if (ret) { + session_put(session); + if (ret != LTTNG_OK) { goto end; } } else { struct ltt_session_list *list = session_get_list(); cds_list_for_each_entry(session, &list->head, list) { + if (!session_get(session)) { + continue; + } session_lock(session); ret = save_session(session, attr, creds); session_unlock(session); - + session_put(session); /* Don't abort if we don't have the required permissions. */ - if (ret && ret != LTTNG_ERR_EPERM) { + if (ret != LTTNG_OK && ret != LTTNG_ERR_EPERM) { goto end; } }