+ break;
+ default:
+ ret = LTTNG_ERR_UNK;
+ goto error_unlock;
+ }
+
+ kernel_wait_quiescent(kernel_tracer_fd);
+ break;
+ }
+ case LTTNG_DOMAIN_UST:
+ {
+ struct ltt_ust_channel *uchan;
+ struct ltt_ust_session *usess;
+
+ usess = session->ust_session;
+
+ if (validate_ust_event_name(event_name)) {
+ ret = LTTNG_ERR_INVALID_EVENT_NAME;
+ goto error_unlock;
+ }
+
+ /*
+ * If a non-default channel has been created in the
+ * session, explicitly require that -c chan_name needs
+ * to be provided.
+ */
+ if (usess->has_non_default_channel && channel_name[0] == '\0') {
+ ret = LTTNG_ERR_NEED_CHANNEL_NAME;
+ goto error_unlock;
+ }
+
+ uchan = trace_ust_find_channel_by_name(usess->domain_global.channels,
+ channel_name);
+ if (uchan == NULL) {
+ ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
+ goto error_unlock;
+ }
+
+ switch (event->type) {
+ case LTTNG_EVENT_ALL:
+ /*
+ * An empty event name means that everything
+ * should be disabled.
+ */
+ if (event->name[0] == '\0') {
+ ret = event_ust_disable_all_tracepoints(usess, uchan);
+ } else {
+ ret = event_ust_disable_tracepoint(usess, uchan,
+ event_name);
+ }
+ if (ret != LTTNG_OK) {
+ goto error_unlock;
+ }
+ break;
+ default:
+ ret = LTTNG_ERR_UNK;
+ goto error_unlock;
+ }
+
+ DBG3("Disable UST event %s in channel %s completed", event_name,
+ channel_name);
+ break;
+ }
+ case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_JUL:
+ case LTTNG_DOMAIN_PYTHON:
+ {
+ struct agent *agt;
+ struct ltt_ust_session *usess = session->ust_session;
+
+ assert(usess);
+
+ switch (event->type) {
+ case LTTNG_EVENT_ALL:
+ break;
+ default:
+ ret = LTTNG_ERR_UNK;
+ goto error_unlock;
+ }
+
+ agt = trace_ust_find_agent(usess, domain);
+ if (!agt) {
+ ret = -LTTNG_ERR_UST_EVENT_NOT_FOUND;
+ goto error_unlock;
+ }
+ /*
+ * An empty event name means that everything
+ * should be disabled.
+ */
+ if (event->name[0] == '\0') {
+ ret = event_agent_disable_all(usess, agt);
+ } else {
+ ret = event_agent_disable(usess, agt, event_name);
+ }
+ if (ret != LTTNG_OK) {
+ goto error_unlock;
+ }
+
+ break;
+ }
+ default:
+ ret = LTTNG_ERR_UND;
+ goto error_unlock;
+ }
+
+ ret = LTTNG_OK;
+
+error_unlock:
+ rcu_read_unlock();
+error:
+ return ret;
+}
+
+/*
+ * Command LTTNG_ADD_CONTEXT processed by the client thread.
+ */
+int cmd_add_context(struct ltt_session *session, enum lttng_domain_type domain,
+ char *channel_name, struct lttng_event_context *ctx, int kwpipe)
+{
+ int ret, chan_kern_created = 0, chan_ust_created = 0;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ assert(session->kernel_session);
+
+ if (session->kernel_session->channel_count == 0) {
+ /* Create default channel */
+ ret = channel_kernel_create(session->kernel_session, NULL, kwpipe);
+ if (ret != LTTNG_OK) {
+ goto error;
+ }
+ chan_kern_created = 1;
+ }
+ /* Add kernel context to kernel tracer */
+ ret = context_kernel_add(session->kernel_session, ctx, channel_name);
+ if (ret != LTTNG_OK) {
+ goto error;
+ }
+ break;
+ case LTTNG_DOMAIN_UST:
+ {
+ struct ltt_ust_session *usess = session->ust_session;
+ unsigned int chan_count;
+
+ assert(usess);
+
+ chan_count = lttng_ht_get_count(usess->domain_global.channels);
+ if (chan_count == 0) {
+ struct lttng_channel *attr;
+ /* Create default channel */
+ attr = channel_new_default_attr(domain, usess->buffer_type);
+ if (attr == NULL) {
+ ret = LTTNG_ERR_FATAL;
+ goto error;
+ }
+
+ ret = channel_ust_create(usess, attr, usess->buffer_type);
+ if (ret != LTTNG_OK) {
+ free(attr);
+ goto error;
+ }
+ free(attr);
+ chan_ust_created = 1;