+ retval = ust_buffers_get_subbuf(buf, consumed_old);
+ if (retval < 0) {
+ WARN("missed buffer?");
+ }
+
+unlock_traces:
+ ltt_unlock_traces();
+
+ return retval;
+}
+
+
+static int notify_buffer_mapped(const char *trace_name,
+ const char *ch_name,
+ int ch_cpu)
+{
+ int retval = 0;
+ struct ust_trace *trace;
+ struct ust_channel *channel;
+ struct ust_buffer *buf;
+
+ DBG("get_buffer_fd");
+
+ ltt_lock_traces();
+ trace = _ltt_trace_find(trace_name);
+
+ if (!trace) {
+ retval = -ENODATA;
+ DBG("Cannot find trace. It was likely destroyed by the user.");
+ goto unlock_traces;
+ }
+
+ channel = find_channel(ch_name, trace);
+ if (!channel) {
+ retval = -ENODATA;
+ ERR("unable to find channel");
+ goto unlock_traces;
+ }
+
+ buf = channel->buf[ch_cpu];
+
+ /* Being here is the proof the daemon has mapped the buffer in its
+ * memory. We may now decrement buffers_to_export.
+ */
+ if (uatomic_read(&buf->consumed) == 0) {
+ DBG("decrementing buffers_to_export");
+ CMM_STORE_SHARED(buffers_to_export, CMM_LOAD_SHARED(buffers_to_export)-1);
+ }
+
+ /* The buffer has been exported, ergo, we can add it to the
+ * list of open buffers
+ */
+ cds_list_add(&buf->open_buffers_list, &open_buffers_list);
+
+unlock_traces:
+ ltt_unlock_traces();
+
+ return retval;
+}
+
+static int put_subbuffer(const char *trace_name, const char *ch_name,
+ int ch_cpu, long consumed_old)
+{
+ int retval = 0;
+ struct ust_trace *trace;
+ struct ust_channel *channel;
+ struct ust_buffer *buf;
+
+ DBG("put_subbuf");
+
+ ltt_lock_traces();
+ trace = _ltt_trace_find(trace_name);
+
+ if (!trace) {
+ retval = -ENODATA;
+ DBG("Cannot find trace. It was likely destroyed by the user.");
+ goto unlock_traces;
+ }
+
+ channel = find_channel(ch_name, trace);
+ if (!channel) {
+ retval = -ENODATA;
+ ERR("unable to find channel");
+ goto unlock_traces;
+ }
+
+ buf = channel->buf[ch_cpu];
+
+ retval = ust_buffers_put_subbuf(buf, consumed_old);
+ if (retval < 0) {
+ WARN("ust_buffers_put_subbuf: error (subbuf=%s_%d)",
+ ch_name, ch_cpu);
+ } else {
+ DBG("ust_buffers_put_subbuf: success (subbuf=%s_%d)",
+ ch_name, ch_cpu);
+ }
+
+unlock_traces:
+ ltt_unlock_traces();
+
+ return retval;
+}
+
+static void listener_cleanup(void *ptr)
+{
+ ustcomm_del_named_sock(listen_sock, 0);
+}
+
+static void force_subbuf_switch()
+{
+ struct ust_buffer *buf;
+
+ cds_list_for_each_entry(buf, &open_buffers_list,
+ open_buffers_list) {
+ ltt_force_switch(buf, FORCE_FLUSH);
+ }
+}
+
+/* Simple commands are those which need only respond with a return value. */
+static int process_simple_client_cmd(int command, char *recv_buf)
+{
+ int result;
+
+ switch(command) {
+ case SET_SOCK_PATH:
+ {
+ struct ustcomm_single_field *sock_msg;
+ sock_msg = (struct ustcomm_single_field *)recv_buf;
+ result = ustcomm_unpack_single_field(sock_msg);
+ if (result < 0) {
+ return result;