add feature to enable/disable markers
authorPierre-Marc Fournier <pierre-marc.fournier@polymtl.ca>
Tue, 5 May 2009 20:36:22 +0000 (16:36 -0400)
committerPierre-Marc Fournier <pierre-marc.fournier@polymtl.ca>
Tue, 5 May 2009 20:36:22 +0000 (16:36 -0400)
libust/tracectl.c
libustcomm/ustcomm.c
ust/ust.c

index 2101d5c4c3725e8de547fbf815237cbff988a3b3..b3dd4c207ab731953036f8c2f09518b39e93c40c 100644 (file)
@@ -68,7 +68,7 @@ struct blocked_consumer {
        struct list_head list;
 };
 
-static void print_markers(void)
+static void print_markers(FILE *fp)
 {
        struct marker_iter iter;
 
@@ -77,7 +77,7 @@ static void print_markers(void)
        marker_iter_start(&iter);
 
        while(iter.marker) {
-               fprintf(stderr, "marker: %s_%s \"%s\"\n", iter.marker->channel, iter.marker->name, iter.marker->format);
+               fprintf(fp, "marker: %s_%s %d \"%s\"\n", iter.marker->channel, iter.marker->name, (int)imv_read(iter.marker->state), iter.marker->format);
                marker_iter_next(&iter);
        }
        unlock_markers();
@@ -232,7 +232,48 @@ int listener_main(void *p)
                len = strlen(recvbuf);
 
                if(!strcmp(recvbuf, "print_markers")) {
-                       print_markers();
+                       print_markers(stderr);
+               }
+               else if(!strcmp(recvbuf, "list_markers")) {
+                       char *ptr;
+                       size_t size;
+                       FILE *fp;
+
+                       fp = open_memstream(&ptr, &size);
+                       print_markers(fp);
+                       fclose(fp);
+
+                       result = ustcomm_send_reply(&ustcomm_app.server, ptr, &src);
+
+                       free(ptr);
+               }
+               else if(!strcmp(recvbuf, "start")) {
+                       /* start is an operation that setups the trace, allocates it and starts it */
+                       result = ltt_trace_setup(trace_name);
+                       if(result < 0) {
+                               ERR("ltt_trace_setup failed");
+                               return;
+                       }
+
+                       result = ltt_trace_set_type(trace_name, trace_type);
+                       if(result < 0) {
+                               ERR("ltt_trace_set_type failed");
+                               return;
+                       }
+
+                       result = ltt_trace_alloc(trace_name);
+                       if(result < 0) {
+                               ERR("ltt_trace_alloc failed");
+                               return;
+                       }
+
+                       inform_consumer_daemon();
+
+                       result = ltt_trace_start(trace_name);
+                       if(result < 0) {
+                               ERR("ltt_trace_start failed");
+                               continue;
+                       }
                }
                else if(!strcmp(recvbuf, "trace_setup")) {
                        DBG("trace setup");
@@ -551,6 +592,42 @@ int listener_main(void *p)
                        free(channel_name);
                        free(consumed_old_str);
                }
+               else if(nth_token_is(recvbuf, "enable_marker", 0) == 1) {
+                       char *channel_slash_name = nth_token(recvbuf, 1);
+                       char channel_name[256]="";
+                       char marker_name[256]="";
+                       struct marker_iter iter;
+
+                       result = sscanf(channel_slash_name, "%255[^/]/%255s", channel_name, marker_name);
+
+                       if(channel_name == NULL || marker_name == NULL) {
+                               WARN("invalid marker name");
+                               goto next_cmd;
+                       }
+                       printf("%s %s\n", channel_name, marker_name);
+
+                       result = ltt_marker_connect(channel_name, marker_name, "default");
+                       if(result < 0) {
+                               WARN("could not enable marker; channel=%s, name=%s", channel_name, marker_name);
+                       }
+               }
+               else if(nth_token_is(recvbuf, "disable_marker", 0) == 1) {
+                       char *channel_slash_name = nth_token(recvbuf, 1);
+                       char *marker_name;
+                       char *channel_name;
+                       struct marker_iter iter;
+
+                       result = sscanf(channel_slash_name, "%a[^/]/%as", &channel_name, &marker_name);
+
+                       if(marker_name == NULL) {
+                       }
+                       printf("%s %s\n", channel_name, marker_name);
+
+                       result = ltt_marker_disconnect(channel_name, marker_name, "default");
+                       if(result < 0) {
+                               WARN("could not disable marker; channel=%s, name=%s", channel_name, marker_name);
+                       }
+               }
 //             else if(nth_token_is(recvbuf, "get_notifications", 0) == 1) {
 //                     struct ltt_trace_struct *trace;
 //                     char trace_name[] = "auto";
@@ -780,7 +857,6 @@ static void __attribute__((constructor(1000))) init()
                        ERR("ltt_trace_start failed");
                        return;
                }
-               //start_consumer();
                inform_consumer_daemon();
        }
 
index e19118347ce3fd364aa1ec75cadb0f74fcf20550..004cdb001f340e355574c87679f5f82bedf81b41 100644 (file)
@@ -49,18 +49,20 @@ char *strdup_malloc(const char *s)
        return retval;
 }
 
-static void signal_process(pid_t pid)
+static int signal_process(pid_t pid)
 {
        int result;
 
        result = kill(pid, UST_SIGNAL);
        if(result == -1) {
                PERROR("kill");
-               return;
+               return -1;
        }
 
        /* FIXME: should wait in a better way */
-       sleep(1);
+       //sleep(1);
+
+       return 0;
 }
 
 static int send_message_fd(int fd, const char *msg)
@@ -113,8 +115,13 @@ static int send_message_path(const char *path, const char *msg, int signalpid)
                return -1;
        }
 
-       if(signalpid >= 0)
-               signal_process(signalpid);
+       if(signalpid >= 0) {
+               result = signal_process(signalpid);
+               if(result == -1) {
+                       ERR("could not signal process");
+                       return -1;
+               }
+       }
 
        result = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
        if(result == -1) {
@@ -438,8 +445,13 @@ int ustcomm_connect_path(char *path, struct ustcomm_connection *conn, pid_t sign
                return -1;
        }
 
-       if(signalpid >= 0)
-               signal_process(signalpid);
+       if(signalpid >= 0) {
+               result = signal_process(signalpid);
+               if(result == -1) {
+                       ERR("could not signal process");
+                       return -1;
+               }
+       }
 
        result = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
        if(result == -1) {
index 3f6bf1d0110aebea01c7f1bb01b15faeb22a8344..2f7a6bd76c3f7ff6e202bd0dc43971dcd201050f 100644 (file)
--- a/ust/ust.c
+++ b/ust/ust.c
 
 #include "ustcomm.h"
 
-void parse_opts(int argc, char **argv)
+struct ust_opts {
+       char *cmd;
+       pid_t *pids;
+       int take_reply;
+};
+
+int parse_opts_long(int argc, char **argv, struct ust_opts *opts)
 {
-       int flags, opt;
-       int nsecs, tfnd;
-
-       nsecs = 0;
-       tfnd = 0;
-       flags = 0;
-       while ((opt = getopt(argc, argv, "nt:")) != -1) {
-               switch (opt) {
-               case 'n':
-                       flags = 1;
-                       break;
-               case 't':
-                       nsecs = atoi(optarg);
-                       tfnd = 1;
-                       break;
-               default:        /* '?' */
-                       fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
-                               argv[0]);
-                       exit(EXIT_FAILURE);
+       int c;
+       int digit_optind = 0;
+
+       opts->cmd = NULL;
+       opts->pids = NULL;
+       opts->take_reply = 0;
+
+       while (1) {
+               int this_option_optind = optind ? optind : 1;
+               int option_index = 0;
+               static struct option long_options[] = {
+                       {"start-trace", 0, 0, 1000},
+                       {"stop-trace", 0, 0, 1001},
+                       {"destroy-trace", 0, 0, 1002},
+                       {"list-markers", 0, 0, 1004},
+                       {"print-markers", 0, 0, 1005},
+                       {"pid", 1, 0, 1006},
+                       {"enable-marker", 1, 0, 1007},
+                       {"disable-marker", 1, 0, 1008},
+                       {"start", 0, 0, 1009},
+                       {0, 0, 0, 0}
+               };
+
+               c = getopt_long(argc, argv, "", long_options, &option_index);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 0:
+                       printf("option %s", long_options[option_index].name);
+                       if (optarg)
+                               printf(" with arg %s", optarg);
+                       printf("\n");
+                       break;
+
+               case 1000:
+                       opts->cmd = strdup("trace_start");
+                       break;
+               case 1001:
+                       opts->cmd = strdup("trace_stop");
+                       break;
+               case 1009:
+                       opts->cmd = strdup("start");
+                       break;
+               case 1002:
+                       opts->cmd = strdup("trace_destroy");
+                       break;
+               case 1004:
+                       opts->cmd = strdup("list_markers");
+                       opts->take_reply = 1;
+                       break;
+               case 1007:
+                       asprintf(&opts->cmd, "enable_marker %s", optarg);
+                       break;
+               case 1008:
+                       asprintf(&opts->cmd, "disable_marker %s", optarg);
+                       break;
+
+               default:
+                       /* unknown option or other error; error is printed by getopt, just return */
+                       return 1;
                }
        }
 
-       printf("flags=%d; tfnd=%d; optind=%d\n", flags, tfnd, optind);
+       if(argc - optind > 0) {
+               int i;
+               int pididx=0;
+               opts->pids = malloc((argc-optind+1) * sizeof(pid_t));
 
-       if (optind >= argc) {
-               fprintf(stderr, "Expected argument after options\n");
-               exit(EXIT_FAILURE);
+               for(i=optind; i<argc; i++) {
+                       opts->pids[pididx++] = atoi(argv[i]);
+               }
+               opts->pids[pididx] = -1;
        }
 
-       printf("name argument = %s\n", argv[optind]);
-
-       /* Other code omitted */
+       return 0;
+}
 
-       exit(EXIT_SUCCESS);
+char *progname = NULL;
 
+void usage(void)
+{
+       fprintf(stderr, "usage: %s [OPTIONS] OPERATION PID...\n", progname);
+       fprintf(stderr, "\nControl the tracing of a process that supports LTTng Userspace Tracing.\n\
+\n\
+Operations:\n\
+\t--start-trace\tStart tracing\n\
+\t--stop-trace\tStop tracing\n\
+\t--destroy-trace\tDestroy the trace\n\
+\t--enable-marker CHANNEL_NAME/MARKER_NAME\tEnable a marker\n\
+\t--disable-marker CHANNEL_NAME/MARKER_NAME\tDisable a marker\n\
+\t--list-markers\tList the markers of the process and their state\n\
+\n\
+");
 }
 
 int main(int argc, char *argv[])
 {
-       pid_t pid = atoi(argv[1]);
+       pid_t *pidit;
+       //char *msg = argv[2];
+       struct ustcomm_connection conn;
+       int result;
+       struct ust_opts opts;
 
-       char *msg = argv[2];
+       progname = argv[0];
 
-       struct ustcomm_connection conn;
+       if(argc <= 1) {
+               fprintf(stderr, "No operation specified.\n");
+               usage();
+               exit(EXIT_FAILURE);
+       }
+
+       result = parse_opts_long(argc, argv, &opts);
+       if(result) {
+               usage();
+               exit(EXIT_FAILURE);
+       }
+
+       if(opts.pids == NULL) {
+               fprintf(stderr, "No pid specified.\n");
+               usage();
+               exit(EXIT_FAILURE);
+       }
+       if(opts.cmd == NULL) {
+               fprintf(stderr, "No command specified.\n");
+               usage();
+               exit(EXIT_FAILURE);
+       }
+
+       pidit = opts.pids;
+
+       while(*pidit != -1) {
+               char *reply;
+               char **preply;
+
+               if(opts.take_reply)
+                       preply = &reply;
+               else
+                       preply = NULL;
+
+               result = ustcomm_connect_app(*pidit, &conn);
+               if(result) {
+                       fprintf(stderr, "error connecting to process\n");
+                       exit(EXIT_FAILURE);
+               }
+               ustcomm_send_request(&conn, opts.cmd, preply);
+
+               if(opts.take_reply)
+                       printf("%s", reply);
+               pidit++;
+       }
 
-       ustcomm_connect_app(pid, &conn);
-       ustcomm_send_request(&conn, msg, NULL);
+       free(opts.pids);
+       free(opts.cmd);
 
        return 0;
 }
This page took 0.028743 seconds and 4 git commands to generate.