ust: add info exchange between app and ustd
[ust.git] / libtracectl / tracectl.c
index 3c5ff859c7f5f9b15139e86ca11e2f3c4b2d3184..176ee6a92bace99333becc45c65d6a117eabc3ad 100644 (file)
@@ -12,6 +12,8 @@
 #include "localerr.h"
 #include "ustcomm.h"
 
+//#define USE_CLONE
+
 #define UNIX_PATH_MAX 108
 
 #define SOCKETDIR "/tmp/socks"
@@ -45,7 +47,6 @@ struct trctl_msg {
        char payload[94];
 };
 
-pid_t mypid;
 char mysocketfile[UNIX_PATH_MAX] = "";
 //int pfd = -1;
 
@@ -162,12 +163,18 @@ int consumer(void *arg)
 
 void start_consumer(void)
 {
+#ifdef USE_CLONE
        int result;
 
        result = clone(consumer, consumer_stack+sizeof(consumer_stack)-1, CLONE_FS | CLONE_FILES | CLONE_VM | CLONE_SIGHAND | CLONE_THREAD, NULL);
        if(result == -1) {
                perror("clone");
        }
+#else
+       pthread_t thread;
+
+       pthread_create(&thread, NULL, consumer, NULL);
+#endif
 }
 
 static void print_markers(void)
@@ -219,12 +226,16 @@ void notif_cb(void)
 
 static int inform_consumer_daemon(void)
 {
+       ustcomm_request_consumer(getpid(), "metadata");
+       ustcomm_request_consumer(getpid(), "ust");
 }
 
 int listener_main(void *p)
 {
        int result;
 
+       DBG("LISTENER");
+
        for(;;) {
                uint32_t size;
                struct sockaddr_un addr;
@@ -233,8 +244,10 @@ int listener_main(void *p)
                char trace_type[] = "ustrelay";
                char *recvbuf;
                int len;
+               struct ustcomm_source src;
 
-               result = ustcomm_app_recv_message(&ustcomm_app, &recvbuf);
+               result = ustcomm_app_recv_message(&ustcomm_app, &recvbuf, &src);
+               DBG("HERE");
                if(result) {
                        WARN("error in ustcomm_app_recv_message");
                        continue;
@@ -242,9 +255,9 @@ int listener_main(void *p)
 
                DBG("received a message! it's: %s\n", recvbuf);
                len = strlen(recvbuf);
-               if(len && recvbuf[len-1] == '\n') {
-                       recvbuf[len-1] = '\0';
-               }
+               //if(len && recvbuf[len-1] == '\n') {
+               //      recvbuf[len-1] = '\0';
+               //}
 
                if(!strcmp(recvbuf, "print_markers")) {
                        print_markers();
@@ -301,20 +314,170 @@ int listener_main(void *p)
                                return;
                        }
                }
+               else if(nth_token_is(recvbuf, "get_shmid", 0) == 1) {
+                       struct ltt_trace_struct *trace;
+                       char trace_name[] = "auto";
+                       int i;
+                       char *channel_name;
+
+                       DBG("get_shmid");
+
+                       channel_name = nth_token(recvbuf, 1);
+                       if(channel_name == NULL) {
+                               ERR("get_shmid: cannot parse channel");
+                               goto next_cmd;
+                       }
+
+                       ltt_lock_traces();
+                       trace = _ltt_trace_find(trace_name);
+                       ltt_unlock_traces();
+
+                       if(trace == NULL) {
+                               CPRINTF("cannot find trace!");
+                               return 1;
+                       }
+
+                       for(i=0; i<trace->nr_channels; i++) {
+                               struct rchan *rchan = trace->channels[i].trans_channel_data;
+                               struct rchan_buf *rbuf = rchan->buf;
+
+                               if(!strcmp(trace->channels[i].channel_name, channel_name)) {
+                                       char *reply;
+
+                                       DBG("the shmid for the requested channel is %d", rbuf->shmid);
+                                       asprintf(&reply, "%d", rbuf->shmid);
+
+                                       result = ustcomm_send_reply(&ustcomm_app.server, reply, &src);
+                                       if(result) {
+                                               ERR("listener: get_shmid: ustcomm_send_reply failed");
+                                               goto next_cmd;
+                                       }
+
+                                       free(reply);
+
+                                       break;
+                               }
+                       }
+               }
+               else if(nth_token_is(recvbuf, "get_n_subbufs", 0) == 1) {
+                       struct ltt_trace_struct *trace;
+                       char trace_name[] = "auto";
+                       int i;
+                       char *channel_name;
+
+                       DBG("get_n_subbufs");
+
+                       channel_name = nth_token(recvbuf, 1);
+                       if(channel_name == NULL) {
+                               ERR("get_n_subbufs: cannot parse channel");
+                               goto next_cmd;
+                       }
+
+                       ltt_lock_traces();
+                       trace = _ltt_trace_find(trace_name);
+                       ltt_unlock_traces();
+
+                       if(trace == NULL) {
+                               CPRINTF("cannot find trace!");
+                               return 1;
+                       }
+
+                       for(i=0; i<trace->nr_channels; i++) {
+                               struct rchan *rchan = trace->channels[i].trans_channel_data;
+
+                               if(!strcmp(trace->channels[i].channel_name, channel_name)) {
+                                       char *reply;
+
+                                       DBG("the n_subbufs for the requested channel is %d", rchan->n_subbufs);
+                                       asprintf(&reply, "%d", rchan->n_subbufs);
+
+                                       result = ustcomm_send_reply(&ustcomm_app.server, reply, &src);
+                                       if(result) {
+                                               ERR("listener: get_n_subbufs: ustcomm_send_reply failed");
+                                               goto next_cmd;
+                                       }
+
+                                       free(reply);
+
+                                       break;
+                               }
+                       }
+               }
+               else if(nth_token_is(recvbuf, "get_subbuf_size", 0) == 1) {
+                       struct ltt_trace_struct *trace;
+                       char trace_name[] = "auto";
+                       int i;
+                       char *channel_name;
+
+                       DBG("get_subbuf_size");
+
+                       channel_name = nth_token(recvbuf, 1);
+                       if(channel_name == NULL) {
+                               ERR("get_subbuf_size: cannot parse channel");
+                               goto next_cmd;
+                       }
+
+                       ltt_lock_traces();
+                       trace = _ltt_trace_find(trace_name);
+                       ltt_unlock_traces();
+
+                       if(trace == NULL) {
+                               CPRINTF("cannot find trace!");
+                               return 1;
+                       }
+
+                       for(i=0; i<trace->nr_channels; i++) {
+                               struct rchan *rchan = trace->channels[i].trans_channel_data;
+
+                               if(!strcmp(trace->channels[i].channel_name, channel_name)) {
+                                       char *reply;
 
+                                       DBG("the subbuf_size for the requested channel is %d", rchan->subbuf_size);
+                                       asprintf(&reply, "%d", rchan->subbuf_size);
+
+                                       result = ustcomm_send_reply(&ustcomm_app.server, reply, &src);
+                                       if(result) {
+                                               ERR("listener: get_subbuf_size: ustcomm_send_reply failed");
+                                               goto next_cmd;
+                                       }
+
+                                       free(reply);
+
+                                       break;
+                               }
+                       }
+               }
+               else if(nth_token_is(recvbuf, "load_probe_lib", 0) == 1) {
+                       char *libfile;
+
+                       libfile = nth_token(recvbuf, 1);
+
+                       DBG("load_probe_lib loading %s", libfile);
+               }
+
+       next_cmd:
                free(recvbuf);
        }
 }
 
+static char listener_stack[16384];
+
 void create_listener(void)
 {
        int result;
        static char listener_stack[16384];
+       //char *listener_stack = malloc(16384);
 
+#ifdef USE_CLONE
        result = clone(listener_main, listener_stack+sizeof(listener_stack)-1, CLONE_FS | CLONE_FILES | CLONE_VM | CLONE_SIGHAND | CLONE_THREAD, NULL);
        if(result == -1) {
                perror("clone");
        }
+#else
+       pthread_t thread;
+
+       pthread_create(&thread, NULL, listener_main, NULL);
+#endif
 }
 
 /* The signal handler itself. Signals must be setup so there cannot be
@@ -414,7 +577,18 @@ static void __attribute__((constructor(1000))) init()
 
        DBG("UST_TRACE constructor");
 
-       mypid = getpid();
+       /* Must create socket before signal handler to prevent races.
+         */
+       result = init_socket();
+       if(result == -1) {
+               ERR("init_socket error");
+               return;
+       }
+       result = init_signal_handler();
+       if(result == -1) {
+               ERR("init_signal_handler error");
+               return;
+       }
 
        if(getenv("UST_TRACE")) {
                char trace_name[] = "auto";
@@ -457,22 +631,10 @@ static void __attribute__((constructor(1000))) init()
                        ERR("ltt_trace_start failed");
                        return;
                }
-               start_consumer();
+               //start_consumer();
+               inform_consumer_daemon();
        }
 
-       /* Must create socket before signal handler to prevent races
-         * on pfd variable.
-         */
-       result = init_socket();
-       if(result == -1) {
-               ERR("init_socket error");
-               return;
-       }
-       result = init_signal_handler();
-       if(result == -1) {
-               ERR("init_signal_handler error");
-               return;
-       }
 
        return;
 
This page took 0.026445 seconds and 4 git commands to generate.