X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=ustctl%2Fustctl.c;h=c1bbe8ce0155289e2975325b6d5631d5ce45e254;hb=2298f3297443ba26f761e272c45456ed857071bc;hp=501a20eaba3845e8e36ad4991e73c0d5991845a7;hpb=ce3296b66be6225497ebd363457f4ccd5f3a2f7a;p=ust.git diff --git a/ustctl/ustctl.c b/ustctl/ustctl.c index 501a20e..c1bbe8c 100644 --- a/ustctl/ustctl.c +++ b/ustctl/ustctl.c @@ -1,4 +1,5 @@ /* Copyright (C) 2009 Pierre-Marc Fournier + * Copyright (C) 2011 Ericsson AB, Nils Carlson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,329 +23,168 @@ #include #include -#include "ustcomm.h" -#include "ustcmd.h" +#include "ust/ustctl.h" #include "usterr.h" +#include "cli.h" +#include "scanning_functions.h" -enum command { - CREATE_TRACE, - START_TRACE, - STOP_TRACE, - START, - DESTROY, - LIST_MARKERS, - ENABLE_MARKER, - DISABLE_MARKER, - GET_ONLINE_PIDS, - SET_SUBBUF_SIZE, - SET_SUBBUF_NUM, - ALLOC_TRACE, - UNKNOWN -}; - -struct ust_opts { - enum command cmd; - pid_t *pids; - char *regex; -}; - -char *progname = NULL; - -void usage(void) +void usage(const char *process_name) { - fprintf(stderr, "usage: %s COMMAND PIDs...\n", progname); - fprintf(stderr, "\nControl the tracing of a process that supports LTTng Userspace Tracing.\n\ -\n\ -Commands:\n\ - --create-trace\t\t\tCreate trace\n\ - --start-trace\t\t\tStart tracing\n\ - --stop-trace\t\t\tStop tracing\n\ - --destroy-trace\t\t\tDestroy the trace\n\ - --set-subbuf-size \"CHANNEL/bytes\"\tSet the size of subbuffers per channel\n\ - --set-subbuf-num \"CHANNEL/n\"\tSet the number of subbuffers per channel\n\ - --enable-marker \"CHANNEL/MARKER\"\tEnable a marker\n\ - --disable-marker \"CHANNEL/MARKER\"\tDisable a marker\n\ - --list-markers\t\t\tList the markers of the process, their\n\t\t\t\t\t state and format string\n\ -\ -"); + fprintf(stderr, "Usage: %s COMMAND [ARGS]...\n", process_name); + fprintf(stderr, + "Control tracing within a process that supports UST,\n" + " the Userspace Tracing libary\n" + "Options:\n" + " -h[], --help[=] " + "help, for a command if provided\n" + " -l, --list " + "short list of commands\n" + " -e, --extended-list " + "extented list of commands with help\n" + "Commands:\n"); + list_cli_cmds(CLI_DESCRIPTIVE_LIST); } -int parse_opts_long(int argc, char **argv, struct ust_opts *opts) +struct option options[] = { - int c; - - opts->pids = NULL; - opts->regex = NULL; - - while (1) { - int option_index = 0; - static struct option long_options[] = { - {"create-trace", 0, 0, 1012}, - {"alloc-trace", 0, 0, 1015}, - {"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}, - {"help", 0, 0, 'h'}, - /*{"version", 0, 0, 1010},*/ - {"online-pids", 0, 0, 1011}, - {"set-subbuf-size", 1, 0, 1013}, - {"set-subbuf-num", 1, 0, 1014}, - {0, 0, 0, 0} - }; + {"help", 2, NULL, 'h'}, + {"list", 0, NULL, 'l'}, + {"extended-list", 0, NULL, 'e'}, + {NULL, 0, NULL, 0}, +}; - c = getopt_long(argc, argv, "h", long_options, &option_index); - if (c == -1) - break; +int main(int argc, char *argv[]) +{ + struct cli_cmd *cli_cmd; + int opt; - switch (c) { - case 0: - printf("option %s", long_options[option_index].name); - if (optarg) - printf(" with arg %s", optarg); - printf("\n"); - break; + if(argc <= 1) { + fprintf(stderr, "No operation specified.\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } - case 1000: - opts->cmd = START_TRACE; - break; - case 1001: - opts->cmd = STOP_TRACE; - break; - case 1009: - opts->cmd = START; - break; - case 1002: - opts->cmd = DESTROY; - break; - case 1004: - opts->cmd = LIST_MARKERS; - break; - case 1007: - opts->cmd = ENABLE_MARKER; - opts->regex = strdup(optarg); - break; - case 1008: - opts->cmd = DISABLE_MARKER; - opts->regex = strdup(optarg); - break; - case 1011: - opts->cmd = GET_ONLINE_PIDS; - break; + while ((opt = getopt_long(argc, argv, "+h::le", + options, NULL)) != -1) { + switch (opt) { case 'h': - usage(); - exit(0); -/* - case 1010: - printf("Version 0.1\n"); - break; -*/ - case 1012: - opts->cmd = CREATE_TRACE; - break; - case 1013: - opts->cmd = SET_SUBBUF_SIZE; - opts->regex = strdup(optarg); - break; - case 1014: - opts->cmd = SET_SUBBUF_NUM; - opts->regex = strdup(optarg); + if (!optarg) { + usage(argv[0]); + } else { + if (cli_print_help(optarg)) { + fprintf(stderr, "No such command %s\n", + optarg); + } + } + exit(EXIT_FAILURE); break; - case 1015: - opts->cmd = ALLOC_TRACE; + case 'l': + list_cli_cmds(CLI_SIMPLE_LIST); + exit(EXIT_FAILURE); break; + case 'e': + list_cli_cmds(CLI_EXTENDED_LIST); + exit(EXIT_FAILURE); default: - /* unknown option or other error; error is - printed by getopt, just return */ - opts->cmd = UNKNOWN; - return 1; + fprintf(stderr, "Unknown option\n"); + break; } } - if (argc - optind > 0 && opts->cmd != GET_ONLINE_PIDS) { - int i; - int pididx=0; - opts->pids = malloc((argc-optind+1) * sizeof(pid_t)); - - for(i=optind; ipids[pididx++] = (pid_t) tmp; - } - opts->pids[pididx] = -1; + cli_cmd = find_cli_cmd(argv[optind]); + if (!cli_cmd) { + fprintf(stderr, "No such command %s\n", + argv[optind]); + exit(EXIT_FAILURE); } + cli_dispatch_cmd(cli_cmd, argc - optind, &argv[optind]); + return 0; } -int main(int argc, char *argv[]) +static int list_trace_events(int argc, char *argv[]) { - pid_t *pidit; - int result; - struct ust_opts opts; + struct trace_event_status *tes = NULL; + int i; + pid_t pid; - progname = argv[0]; + pid = parse_pid(argv[1]); - if(argc <= 1) { - fprintf(stderr, "No operation specified.\n"); - usage(); - exit(EXIT_FAILURE); + if (ustctl_get_tes(&tes, pid)) { + ERR("error while trying to list " + "trace_events for PID %u\n", + pid); + return -1; } - - result = parse_opts_long(argc, argv, &opts); - if(result) { - fprintf(stderr, "\n"); - usage(); - exit(EXIT_FAILURE); - } - - if(opts.pids == NULL && opts.cmd != GET_ONLINE_PIDS) { - fprintf(stderr, "No pid specified.\n"); - usage(); - exit(EXIT_FAILURE); + i = 0; + for (i = 0; tes[i].name; i++) { + printf("{PID: %u, trace_event: %s}\n", + pid, + tes[i].name); } - if(opts.cmd == UNKNOWN) { - fprintf(stderr, "No command specified.\n"); - usage(); - exit(EXIT_FAILURE); - } - if (opts.cmd == GET_ONLINE_PIDS) { - pid_t *pp = ustcmd_get_online_pids(); - unsigned int i = 0; - - if (pp) { - while (pp[i] != 0) { - printf("%u\n", (unsigned int) pp[i]); - ++i; - } - free(pp); - } - - exit(EXIT_SUCCESS); - } - - pidit = opts.pids; - struct marker_status *cmsf = NULL; - - while(*pidit != -1) { - switch (opts.cmd) { - case CREATE_TRACE: - result = ustcmd_create_trace(*pidit); - if (result) { - ERR("error while trying to create trace with PID %u\n", (unsigned int) *pidit); - break; - } - break; - - case START_TRACE: - result = ustcmd_start_trace(*pidit); - if (result) { - ERR("error while trying to for trace with PID %u\n", (unsigned int) *pidit); - break; - } - //printf("sucessfully started trace for PID %u\n", (unsigned int) *pidit); - break; - - case STOP_TRACE: - result = ustcmd_stop_trace(*pidit); - if (result) { - ERR("error while trying to stop trace for PID %u\n", (unsigned int) *pidit); - break; - } - //printf("sucessfully stopped trace for PID %u\n", (unsigned int) *pidit); - break; + ustctl_free_tes(tes); - case START: - result = ustcmd_setup_and_start(*pidit); - if (result) { - ERR("error while trying to setup/start trace for PID %u\n", (unsigned int) *pidit); - break; - } - //printf("sucessfully setup/started trace for PID %u\n", (unsigned int) *pidit); - break; - - case DESTROY: - result = ustcmd_destroy_trace(*pidit); - if (result) { - ERR("error while trying to destroy trace with PID %u\n", (unsigned int) *pidit); - break; - } - //printf("sucessfully destroyed trace for PID %u\n", (unsigned int) *pidit); - break; - - case LIST_MARKERS: - cmsf = NULL; - if (ustcmd_get_cmsf(&cmsf, *pidit)) { - fprintf(stderr, - "error while trying to list markers for" - " PID %u\n", (unsigned int) *pidit); - break; - } - unsigned int i = 0; - while (cmsf[i].channel != NULL) { - printf("{PID: %u, channel/marker: %s/%s, " - "state: %u, fmt: %s}\n", - (unsigned int) *pidit, - cmsf[i].channel, - cmsf[i].marker, - cmsf[i].state, - cmsf[i].fs); - ++i; - } - ustcmd_free_cmsf(cmsf); - break; + return 0; +} - case ENABLE_MARKER: - if(opts.regex) - ustcmd_set_marker_state(opts.regex, 1, *pidit); - break; - case DISABLE_MARKER: - if(opts.regex) - ustcmd_set_marker_state(opts.regex, 0, *pidit); - break; +static int set_sock_path(int argc, char *argv[]) +{ + pid_t pid; - case SET_SUBBUF_SIZE: - ustcmd_set_subbuf_size(opts.regex, *pidit); - break; + pid = parse_pid(argv[1]); - case SET_SUBBUF_NUM: - ustcmd_set_subbuf_num(opts.regex, *pidit); - break; + if (ustctl_set_sock_path(argv[2], pid)) { + ERR("error while trying to set sock path for PID %u\n", pid); + return -1; + } - case ALLOC_TRACE: - result = ustcmd_alloc_trace(*pidit); - if (result) { - ERR("error while trying to alloc trace with PID %u\n", (unsigned int) *pidit); - break; - } - break; + return 0; +} - default: - ERR("unknown command\n"); - break; - } +static int get_sock_path(int argc, char *argv[]) +{ + pid_t pid; + char *sock_path; - pidit++; - } + pid = parse_pid(argv[1]); - if (opts.pids != NULL) { - free(opts.pids); - } - if (opts.regex != NULL) { - free(opts.regex); + if (ustctl_get_sock_path(&sock_path, pid)) { + ERR("error while trying to get sock path for PID %u\n", pid); + return -1; } + printf("The socket path is %s\n", sock_path); + free(sock_path); return 0; } +struct cli_cmd __cli_cmds general_cmds[] = { + { + .name = "list-trace-events", + .description = "List trace-events for a given pid", + .help_text = "list-trace-events \n" + "List the trace-events in a process\n", + .function = list_trace_events, + .desired_args = 1, + .desired_args_op = CLI_EQ, + }, + { + .name = "set-sock-path", + .description = "Set the path to the consumer daemon socket", + .help_text = "set-sock-path \n" + "Set the path to the consumer daemon socket\n", + .function = set_sock_path, + .desired_args = 2, + .desired_args_op = CLI_EQ, + }, + { + .name = "get-sock-path", + .description = "Get the path to the consumer daemon socket", + .help_text = "get-sock-path \n" + "Get the path to the consumer daemon socket\n", + .function = get_sock_path, + .desired_args = 1, + .desired_args_op = CLI_EQ, + }, +};