+ 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");
+ STORE_SHARED(buffers_to_export, LOAD_SHARED(buffers_to_export)-1);
+ }
+
+ /* The buffer has been exported, ergo, we can add it to the
+ * list of open buffers
+ */
+ 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;
+
+ 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)
+{
+ switch(command) {
+ case SET_SOCK_PATH:
+ {
+ struct ustcomm_sock_path *sock_msg;
+ sock_msg = (struct ustcomm_sock_path *)recv_buf;
+ sock_msg->sock_path =
+ ustcomm_restore_ptr(sock_msg->sock_path,
+ sock_msg->data,
+ sizeof(sock_msg->data));
+ if (!sock_msg->sock_path) {
+
+ return -EINVAL;