*/
s64 pidunique = -1LL;
+/* The process pid is used to detect a non-traceable fork
+ * and allow the non-traceable fork to be ignored
+ * by destructor sequences in libust
+ */
+static pid_t processpid = 0;
+
static struct ustcomm_header _receive_header;
static struct ustcomm_header *receive_header = &_receive_header;
static char receive_buffer[USTCOMM_BUFFER_SIZE];
static void request_buffer_consumer(int sock,
- const char *channel,
- int cpu)
+ const char *trace,
+ const char *channel,
+ int cpu)
{
struct ustcomm_header send_header, recv_header;
struct ustcomm_buffer_info buf_inf;
result = ustcomm_pack_buffer_info(&send_header,
&buf_inf,
+ trace,
channel,
cpu);
/* iterate on all cpus */
for (j=0; j<trace->channels[i].n_cpus; j++) {
ch_name = trace->channels[i].channel_name;
- request_buffer_consumer(sock, ch_name, j);
+ request_buffer_consumer(sock, trace_name,
+ ch_name, j);
STORE_SHARED(buffers_to_export,
LOAD_SHARED(buffers_to_export)+1);
}
/* 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;
- char trace_type[] = "ustrelay";
- char trace_name[] = "auto";
-
switch(command) {
case SET_SOCK_PATH:
{
}
return setenv("UST_DAEMON_SOCKET", sock_msg->sock_path, 1);
}
+
+ case FORCE_SUBBUF_SWITCH:
+ /* FIXME: return codes? */
+ force_subbuf_switch();
+
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+static int process_trace_cmd(int command, char *trace_name)
+{
+ int result;
+ char trace_type[] = "ustrelay";
+
+ switch(command) {
case START:
/* start is an operation that setups the trace, allocates it and starts it */
result = ltt_trace_setup(trace_name);
return result;
}
return 0;
- case FORCE_SUBBUF_SWITCH:
- /* FIXME: return codes? */
- force_subbuf_switch();
-
- break;
-
- default:
- return -EINVAL;
}
return 0;
}
+
static void process_channel_cmd(int sock, int command,
struct ustcomm_channel_info *ch_inf)
{
struct ustcomm_header *reply_header = &_reply_header;
struct ustcomm_channel_info *reply_msg =
(struct ustcomm_channel_info *)send_buffer;
- char trace_name[] = "auto";
int result, offset = 0, num, size;
memset(reply_header, 0, sizeof(*reply_header));
switch (command) {
case GET_SUBBUF_NUM_SIZE:
- result = get_subbuf_num_size(trace_name,
+ result = get_subbuf_num_size(ch_inf->trace,
ch_inf->channel,
&num, &size);
if (result < 0) {
break;
case SET_SUBBUF_NUM:
- reply_header->result = set_subbuf_num(trace_name,
+ reply_header->result = set_subbuf_num(ch_inf->trace,
ch_inf->channel,
ch_inf->subbuf_num);
break;
case SET_SUBBUF_SIZE:
- reply_header->result = set_subbuf_size(trace_name,
+ reply_header->result = set_subbuf_size(ch_inf->trace,
ch_inf->channel,
ch_inf->subbuf_size);
struct ustcomm_header *reply_header = &_reply_header;
struct ustcomm_buffer_info *reply_msg =
(struct ustcomm_buffer_info *)send_buffer;
- char trace_name[] = "auto";
int result, offset = 0, buf_shmid, buf_struct_shmid, buf_pipe_fd;
long consumed_old;
switch (command) {
case GET_BUF_SHMID_PIPE_FD:
- result = get_buffer_shmid_pipe_fd(trace_name, buf_inf->channel,
+ result = get_buffer_shmid_pipe_fd(buf_inf->trace,
+ buf_inf->channel,
buf_inf->ch_cpu,
&buf_shmid,
&buf_struct_shmid,
case NOTIFY_BUF_MAPPED:
reply_header->result =
- notify_buffer_mapped(trace_name,
+ notify_buffer_mapped(buf_inf->trace,
buf_inf->channel,
buf_inf->ch_cpu);
break;
case GET_SUBBUFFER:
- result = get_subbuffer(trace_name, buf_inf->channel,
+ result = get_subbuffer(buf_inf->trace, buf_inf->channel,
buf_inf->ch_cpu, &consumed_old);
if (result < 0) {
reply_header->result = result;
break;
case PUT_SUBBUFFER:
- result = put_subbuffer(trace_name, buf_inf->channel,
+ result = put_subbuffer(buf_inf->trace, buf_inf->channel,
buf_inf->ch_cpu,
buf_inf->consumed_old);
reply_header->result = result;
goto send_response;
}
+ case START:
+ case SETUP_TRACE:
+ case ALLOC_TRACE:
+ case CREATE_TRACE:
+ case START_TRACE:
+ case STOP_TRACE:
+ case DESTROY_TRACE:
+ {
+ struct ustcomm_trace_info *trace_inf =
+ (struct ustcomm_trace_info *)recv_buf;
+
+ result = ustcomm_unpack_trace_info(trace_inf);
+ if (result < 0) {
+ ERR("couldn't unpack trace info");
+ reply_header->result = -EINVAL;
+ goto send_response;
+ }
+
+ reply_header->result =
+ process_trace_cmd(recv_header->command,
+ trace_inf->trace);
+ goto send_response;
+
+ }
default:
reply_header->result =
process_simple_client_cmd(recv_header->command,
* pid, (before and after an exec).
*/
pidunique = make_pidunique();
+ processpid = getpid();
DBG("Tracectl constructor");
static void __attribute__((destructor)) keepalive()
{
+ if (processpid != getpid()) {
+ return;
+ }
+
if (trace_recording() && LOAD_SHARED(buffers_to_export)) {
int total = 0;
DBG("Keeping process alive for consumer daemon...");
/* FIXME: technically, the locks could have been taken before the fork */
DBG("ust: forking");
+ /* Get the pid of the new process */
+ processpid = getpid();
+
/* break lock if necessary */
ltt_unlock_traces();