X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=c1f5a4e70b7ce83545ce0858db2f781b563fdc26;hb=b747c300c074c13b115d7f6d3f35d157e1c33f32;hp=f997cc79b3c6f5a89865250327ccb0477da69900;hpb=72b6f5b6dc9fdd0ff4d49df8a9f010644311e863;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index f997cc79b..c1f5a4e70 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -850,6 +850,16 @@ int cmd_enable_channel(struct ltt_session *session, rcu_read_lock(); + /* + * The ringbuffer (both in user space and kernel) behave badly in overwrite + * mode and with less than 2 subbuf so block it right away and send back an + * invalid attribute error. + */ + if (attr->attr.overwrite && attr->attr.num_subbuf < 2) { + ret = LTTNG_ERR_INVALID; + goto error; + } + switch (domain->type) { case LTTNG_DOMAIN_KERNEL: { @@ -1583,6 +1593,7 @@ error: int cmd_start_trace(struct ltt_session *session) { int ret; + unsigned long nb_chan = 0; struct ltt_kernel_session *ksession; struct ltt_ust_session *usess; @@ -1598,6 +1609,21 @@ int cmd_start_trace(struct ltt_session *session) goto error; } + /* + * Starting a session without channel is useless since after that it's not + * possible to enable channel thus inform the client. + */ + if (usess && usess->domain_global.channels) { + nb_chan += lttng_ht_get_count(usess->domain_global.channels); + } + if (ksession) { + nb_chan += ksession->channel_count; + } + if (!nb_chan) { + ret = LTTNG_ERR_NO_CHANNEL; + goto error; + } + session->enabled = 1; /* Kernel tracing */ @@ -1753,6 +1779,17 @@ int cmd_set_consumer_uri(int domain, struct ltt_session *session, } } + /* + * Make sure to set the session in output mode after we set URI since a + * session can be created without URL (thus flagged in no output mode). + */ + session->output_traces = 1; + if (ksess) { + ksess->output_traces = 1; + } else if (usess) { + usess->output_traces = 1; + } + /* All good! */ ret = LTTNG_OK; @@ -2285,6 +2322,21 @@ int cmd_data_pending(struct ltt_session *session) if (session->enabled) { ret = LTTNG_ERR_SESSION_STARTED; goto error; + } else { + /* + * If stopped, just make sure we've started before else the above call + * will always send that there is data pending. + * + * The consumer assumes that when the data pending command is received, + * the trace has been started before or else no output data is written + * by the streams which is a condition for data pending. So, this is + * *VERY* important that we don't ask the consumer before a start + * trace. + */ + if (!session->started) { + ret = 0; + goto error; + } } if (ksess && ksess->consumer) { @@ -2637,12 +2689,17 @@ static int record_ust_snapshot(struct ltt_ust_session *usess, ret = ust_app_snapshot_record(usess, output, wait, nb_streams); if (ret < 0) { - if (ret == -EINVAL) { + switch (-ret) { + case EINVAL: ret = LTTNG_ERR_INVALID; - goto error_snapshot; + break; + case ENODATA: + ret = LTTNG_ERR_SNAPSHOT_NODATA; + break; + default: + ret = LTTNG_ERR_SNAPSHOT_FAIL; + break; } - - ret = LTTNG_ERR_SNAPSHOT_FAIL; goto error_snapshot; }