-/*
- * Command LTTNG_DISABLE_CONSUMER processed by the client thread.
- */
-int cmd_disable_consumer(int domain, struct ltt_session *session)
-{
- int ret;
- struct ltt_kernel_session *ksess = session->kernel_session;
- struct ltt_ust_session *usess = session->ust_session;
- struct consumer_output *consumer;
-
- assert(session);
-
- if (session->enabled) {
- /* Can't disable consumer on an already started session */
- ret = LTTNG_ERR_TRACE_ALREADY_STARTED;
- goto error;
- }
-
- if (!session->start_consumer) {
- ret = LTTNG_ERR_NO_CONSUMER;
- goto error;
- }
-
- switch (domain) {
- case 0:
- DBG("Disable tracing session %s consumer", session->name);
- consumer = session->consumer;
- break;
- case LTTNG_DOMAIN_KERNEL:
- /* Code flow error if we don't have a kernel session here. */
- assert(ksess);
-
- DBG("Disabling kernel consumer");
- consumer = ksess->consumer;
-
- break;
- case LTTNG_DOMAIN_UST:
- /* Code flow error if we don't have a UST session here. */
- assert(usess);
-
- DBG("Disabling UST consumer");
- consumer = usess->consumer;
-
- break;
- default:
- ret = LTTNG_ERR_UNKNOWN_DOMAIN;
- goto error;
- }
-
- if (consumer) {
- consumer->enabled = 0;
- /* Success at this point */
- ret = LTTNG_OK;
- } else {
- ret = LTTNG_ERR_NO_CONSUMER;
- }
-
-error:
- return ret;
-}
-
-/*
- * Command LTTNG_ENABLE_CONSUMER processed by the client thread.
- */
-int cmd_enable_consumer(int domain, struct ltt_session *session)
-{
- int ret;
- struct ltt_kernel_session *ksess = session->kernel_session;
- struct ltt_ust_session *usess = session->ust_session;
- struct consumer_output *consumer = NULL;
-
- assert(session);
-
- /* Can't enable consumer after session started. */
- if (session->enabled) {
- ret = LTTNG_ERR_TRACE_ALREADY_STARTED;
- goto error;
- }
-
- switch (domain) {
- case 0:
- assert(session->consumer);
- consumer = session->consumer;
- break;
- case LTTNG_DOMAIN_KERNEL:
- /* Code flow error if we don't have a kernel session here. */
- assert(ksess);
-
- /*
- * Check if we have already sent fds to the consumer. In that case,
- * the enable-consumer command can't be used because a start trace
- * had previously occured.
- */
- if (ksess->consumer_fds_sent) {
- ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
- goto error;
- }
-
- consumer = ksess->tmp_consumer;
- if (consumer == NULL) {
- ret = LTTNG_OK;
- /* No temp. consumer output exists. Using the current one. */
- DBG3("No temporary consumer. Using default");
- consumer = ksess->consumer;
- goto error;
- }
-
- switch (consumer->type) {
- case CONSUMER_DST_LOCAL:
- DBG2("Consumer output is local. Creating directory(ies)");
-
- /* Create directory(ies) */
- ret = run_as_mkdir_recursive(consumer->dst.trace_path,
- S_IRWXU | S_IRWXG, session->uid, session->gid);
- if (ret < 0) {
- if (ret != -EEXIST) {
- ERR("Trace directory creation error");
- ret = LTTNG_ERR_FATAL;
- goto error;
- }
- }
- break;
- case CONSUMER_DST_NET:
- DBG2("Consumer output is network. Validating URIs");
- /* Validate if we have both control and data path set. */
- if (!consumer->dst.net.control_isset) {
- ret = LTTNG_ERR_URL_CTRL_MISS;
- goto error;
- }
-
- if (!consumer->dst.net.data_isset) {
- ret = LTTNG_ERR_URL_DATA_MISS;
- goto error;
- }
-
- /* Check established network session state */
- if (session->net_handle == 0) {
- ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
- ERR("Session network handle is not set on enable-consumer");
- goto error;
- }
-
- break;
- }
-
- /*
- * @session-lock
- * This is race free for now since the session lock is acquired before
- * ending up in this function. No other threads can access this kernel
- * session without this lock hence freeing the consumer output object
- * is valid.
- */
- rcu_read_lock();
- /* Destroy current consumer. We are about to replace it */
- consumer_destroy_output(ksess->consumer);
- rcu_read_unlock();
- ksess->consumer = consumer;
- ksess->tmp_consumer = NULL;
-
- break;
- case LTTNG_DOMAIN_UST:
- /* Code flow error if we don't have a UST session here. */
- assert(usess);
-
- /*
- * Check if we have already sent fds to the consumer. In that case,
- * the enable-consumer command can't be used because a start trace
- * had previously occured.
- */
- if (usess->start_trace) {
- ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
- goto error;
- }
-
- consumer = usess->tmp_consumer;
- if (consumer == NULL) {
- ret = LTTNG_OK;
- /* No temp. consumer output exists. Using the current one. */
- DBG3("No temporary consumer. Using default");
- consumer = usess->consumer;
- goto error;
- }
-
- switch (consumer->type) {
- case CONSUMER_DST_LOCAL:
- DBG2("Consumer output is local. Creating directory(ies)");
-
- /* Create directory(ies) */
- ret = run_as_mkdir_recursive(consumer->dst.trace_path,
- S_IRWXU | S_IRWXG, session->uid, session->gid);
- if (ret < 0) {
- if (ret != -EEXIST) {
- ERR("Trace directory creation error");
- ret = LTTNG_ERR_FATAL;
- goto error;
- }
- }
- break;
- case CONSUMER_DST_NET:
- DBG2("Consumer output is network. Validating URIs");
- /* Validate if we have both control and data path set. */
- if (!consumer->dst.net.control_isset) {
- ret = LTTNG_ERR_URL_CTRL_MISS;
- goto error;
- }
-
- if (!consumer->dst.net.data_isset) {
- ret = LTTNG_ERR_URL_DATA_MISS;
- goto error;
- }
-
- /* Check established network session state */
- if (session->net_handle == 0) {
- ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
- DBG2("Session network handle is not set on enable-consumer");
- goto error;
- }
-
- if (consumer->net_seq_index == -1) {
- ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
- DBG2("Network index is not set on the consumer");
- goto error;
- }
-
- break;
- }
-
- /*
- * @session-lock
- * This is race free for now since the session lock is acquired before
- * ending up in this function. No other threads can access this kernel
- * session without this lock hence freeing the consumer output object
- * is valid.
- */
- rcu_read_lock();
- /* Destroy current consumer. We are about to replace it */
- consumer_destroy_output(usess->consumer);
- rcu_read_unlock();
- usess->consumer = consumer;
- usess->tmp_consumer = NULL;
-
- break;
- }
-
- session->start_consumer = 1;
-
- /* Enable it */
- if (consumer) {
- consumer->enabled = 1;
- /* Success at this point */
- ret = LTTNG_OK;
- } else {
- /* Should not really happend... */
- ret = LTTNG_ERR_NO_CONSUMER;
- }
-
-error:
- return ret;
-}
-