+
+ kernel_wait_quiescent();
+ break;
+ }
+ case LTTNG_DOMAIN_UST:
+ case LTTNG_DOMAIN_JUL:
+ case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_PYTHON:
+ {
+ struct ltt_ust_channel *uchan;
+
+ /*
+ * FIXME
+ *
+ * Current agent implementation limitations force us to allow
+ * only one channel at once in "agent" subdomains. Each
+ * subdomain has a default channel name which must be strictly
+ * adhered to.
+ */
+ if (domain->type == LTTNG_DOMAIN_JUL) {
+ if (strncmp(attr.name, DEFAULT_JUL_CHANNEL_NAME,
+ LTTNG_SYMBOL_NAME_LEN)) {
+ ret = LTTNG_ERR_INVALID_CHANNEL_NAME;
+ goto error;
+ }
+ } else if (domain->type == LTTNG_DOMAIN_LOG4J) {
+ if (strncmp(attr.name, DEFAULT_LOG4J_CHANNEL_NAME,
+ LTTNG_SYMBOL_NAME_LEN)) {
+ ret = LTTNG_ERR_INVALID_CHANNEL_NAME;
+ goto error;
+ }
+ } else if (domain->type == LTTNG_DOMAIN_PYTHON) {
+ if (strncmp(attr.name, DEFAULT_PYTHON_CHANNEL_NAME,
+ LTTNG_SYMBOL_NAME_LEN)) {
+ ret = LTTNG_ERR_INVALID_CHANNEL_NAME;
+ goto error;
+ }
+ }
+
+ chan_ht = usess->domain_global.channels;
+
+ uchan = trace_ust_find_channel_by_name(chan_ht, attr.name);
+ if (uchan == NULL) {
+ ret = channel_ust_create(usess, &attr, domain->buf_type);
+ if (attr.name[0] != '\0') {
+ usess->has_non_default_channel = 1;
+ }
+ } else {
+ ret = channel_ust_enable(usess, uchan);
+ }
+ break;
+ }
+ default:
+ ret = LTTNG_ERR_UNKNOWN_DOMAIN;
+ goto error;
+ }
+
+ if (ret == LTTNG_OK && attr.attr.output != LTTNG_EVENT_MMAP) {
+ session->has_non_mmap_channel = true;
+ }
+error:
+ rcu_read_unlock();
+end:
+ return ret;
+}
+
+enum lttng_error_code cmd_add_map(struct command_ctx *cmd_ctx, int sock)
+{
+ int ret;
+ enum lttng_error_code ret_code;
+ size_t map_len;
+ struct lttng_payload map_payload;
+ ssize_t sock_recv_len;
+ struct lttng_map *map = NULL;
+ const struct lttng_credentials cmd_creds = {
+ .uid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.uid),
+ .gid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.gid),
+ };
+
+ lttng_payload_init(&map_payload);
+ map_len = (size_t) cmd_ctx->lsm.u.add_map.length;
+ ret = lttng_dynamic_buffer_set_size(
+ &map_payload.buffer, map_len);
+ if (ret) {
+ ret_code = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ sock_recv_len = lttcomm_recv_unix_sock(
+ sock, map_payload.buffer.data, map_len);
+ if (sock_recv_len < 0 || sock_recv_len != map_len) {
+ ERR("Failed to receive \"register map\" command payload");
+ ret_code = LTTNG_ERR_INVALID_MAP;
+ goto end;
+ }
+
+ /* Deserialize map. */
+ {
+ struct lttng_payload_view view =
+ lttng_payload_view_from_payload(
+ &map_payload, 0, -1);
+
+ if (lttng_map_create_from_payload(&view, &map) != map_len) {
+ ERR("Invalid map payload received in \"add map\" command");
+ ret_code = LTTNG_ERR_INVALID_MAP;
+ goto end;
+ }
+ }
+
+ switch (lttng_map_get_domain(map)) {
+ case LTTNG_DOMAIN_KERNEL:
+ ret_code = map_kernel_add(cmd_ctx->session->kernel_session, map);
+ if (ret_code != LTTNG_OK) {
+ ERR("Creating a new kernel map: %s", lttng_strerror(ret_code));
+ goto end;
+ }
+
+ ret_code = LTTNG_OK;
+ break;
+ case LTTNG_DOMAIN_UST:
+ ret = map_ust_add(cmd_ctx->session->ust_session, map);
+ if (ret) {
+ ERR("Creating a new UST map: %s", lttng_strerror(-ret));
+ ret_code = ret;
+ goto end;
+ }
+
+ ret_code = LTTNG_OK;
+ break;
+ default:
+ abort();
+ }
+
+
+ {
+ struct lttng_triggers *triggers = NULL;
+ enum lttng_trigger_status t_status;
+ unsigned int count, i;
+
+ /*
+ * FRDESO: beware of moving this code. This is currently not
+ * racy because this is executed by the client thread and the
+ * client thread is the thread registering new triggers. If
+ * this code is relocate special care must be taken.
+ */
+ ret_code = notification_thread_command_list_triggers(
+ notification_thread_handle, 0, &triggers);
+ if (ret_code != LTTNG_OK) {
+ ret = -1;
+ goto end;
+ }
+
+ assert(triggers);
+
+ t_status = lttng_triggers_get_count(triggers, &count);
+ if (t_status != LTTNG_TRIGGER_STATUS_OK) {
+ ret = -1;
+ lttng_triggers_destroy(triggers);
+ goto end;
+ }
+
+ for (i = 0; i < count; i++) {
+ const struct lttng_trigger *trigger;
+
+ trigger = lttng_triggers_get_at_index(triggers, i);
+ assert(trigger);
+
+ ret_code = sync_all_tracer_executed_actions(trigger,
+ &cmd_creds, TRACER_EXECUTED_ACTION_STATE_REGISTER);
+ assert(ret_code == LTTNG_OK);
+ }
+
+ lttng_triggers_destroy(triggers);
+ }
+
+ lttng_map_put(map);
+
+end:
+ lttng_payload_reset(&map_payload);
+ return ret_code;
+}
+
+enum lttng_error_code cmd_enable_map(struct ltt_session *session,
+ enum lttng_domain_type domain, char *map_name)
+{
+ struct ltt_ust_session *usess = session->ust_session;
+ enum lttng_error_code ret_code;
+
+ DBG("Enabling map %s for session %s", map_name, session->name);
+
+ rcu_read_lock();
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ {
+ struct ltt_kernel_map *kmap;
+ struct ltt_kernel_session *ksess = session->kernel_session;
+
+ kmap = trace_kernel_get_map_by_name(map_name, ksess);
+ if (kmap == NULL) {
+ ret_code = LTTNG_ERR_KERNEL_MAP_NOT_FOUND;
+ goto error;
+ }
+
+ ret_code = map_kernel_enable(ksess, kmap);
+ if (ret_code != LTTNG_OK) {
+ goto error;
+ }
+ break;
+ }
+ case LTTNG_DOMAIN_UST:
+ {
+ struct ltt_ust_map *umap;
+ struct lttng_ht *map_ht;
+
+ map_ht = usess->domain_global.maps;
+
+ umap = trace_ust_find_map_by_name(map_ht, map_name);
+ if (umap == NULL) {
+ ret_code = LTTNG_ERR_UST_MAP_NOT_FOUND;
+ goto error;
+ }
+
+ ret_code = map_ust_enable(usess, umap);
+ if (ret_code != LTTNG_OK) {
+ goto error;
+ }
+ break;
+ }
+ default:
+ abort();
+ }
+
+ ret_code = LTTNG_OK;
+error:
+ rcu_read_unlock();
+ return ret_code;
+}
+
+enum lttng_error_code cmd_disable_map(struct ltt_session *session,
+ enum lttng_domain_type domain, char *map_name)
+{
+ enum lttng_error_code ret_code;
+
+ rcu_read_lock();
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ {
+ struct ltt_kernel_map *kmap;
+ struct ltt_kernel_session *ksess = session->kernel_session;
+
+ kmap = trace_kernel_get_map_by_name(map_name, ksess);
+ if (kmap == NULL) {
+ ret_code = LTTNG_ERR_KERNEL_MAP_NOT_FOUND;
+ goto error;
+ }
+
+ ret_code = map_kernel_disable(ksess, kmap);
+ if (ret_code != LTTNG_OK) {
+ goto error;
+ }
+ break;
+ }
+ case LTTNG_DOMAIN_UST:
+ {
+ struct ltt_ust_map *umap;
+ struct lttng_ht *map_ht;
+ struct ltt_ust_session *usess = session->ust_session;
+
+ assert(usess);
+
+ map_ht = usess->domain_global.maps;
+
+ umap = trace_ust_find_map_by_name(map_ht, map_name);
+ if (umap == NULL) {
+ ret_code = LTTNG_ERR_UST_MAP_NOT_FOUND;
+ goto error;
+ }
+
+ ret_code = map_ust_disable(usess, umap);
+ if (ret_code != LTTNG_OK) {
+ goto error;
+ }
+ break;
+ }
+ default:
+ abort();
+ }
+
+ ret_code = LTTNG_OK;
+
+error:
+ rcu_read_unlock();
+ return ret_code;
+}
+
+enum lttng_error_code cmd_process_attr_tracker_get_tracking_policy(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy *policy)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+ const struct process_attr_tracker *tracker;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (!session->kernel_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ tracker = kernel_get_process_attr_tracker(
+ session->kernel_session, process_attr);
+ break;
+ case LTTNG_DOMAIN_UST:
+ if (!session->ust_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ tracker = trace_ust_get_process_attr_tracker(
+ session->ust_session, process_attr);
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ goto end;
+ }
+ if (tracker) {
+ *policy = process_attr_tracker_get_tracking_policy(tracker);
+ } else {
+ ret_code = LTTNG_ERR_INVALID;
+ }
+end:
+ return ret_code;
+}
+
+enum lttng_error_code cmd_process_attr_tracker_set_tracking_policy(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy policy)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+
+ switch (policy) {
+ case LTTNG_TRACKING_POLICY_INCLUDE_SET:
+ case LTTNG_TRACKING_POLICY_EXCLUDE_ALL:
+ case LTTNG_TRACKING_POLICY_INCLUDE_ALL:
+ break;
+ default:
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (!session->kernel_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = kernel_process_attr_tracker_set_tracking_policy(
+ session->kernel_session, process_attr, policy);
+ break;
+ case LTTNG_DOMAIN_UST:
+ if (!session->ust_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = trace_ust_process_attr_tracker_set_tracking_policy(
+ session->ust_session, process_attr, policy);
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ break;
+ }
+end:
+ return ret_code;
+}
+
+enum lttng_error_code cmd_process_attr_tracker_inclusion_set_add_value(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (!session->kernel_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = kernel_process_attr_tracker_inclusion_set_add_value(
+ session->kernel_session, process_attr, value);
+ break;
+ case LTTNG_DOMAIN_UST:
+ if (!session->ust_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = trace_ust_process_attr_tracker_inclusion_set_add_value(
+ session->ust_session, process_attr, value);
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ break;
+ }
+end:
+ return ret_code;
+}
+
+enum lttng_error_code cmd_process_attr_tracker_inclusion_set_remove_value(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (!session->kernel_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = kernel_process_attr_tracker_inclusion_set_remove_value(
+ session->kernel_session, process_attr, value);