^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "builtin.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "perf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <subcmd/parse-options.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "data-convert.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "data-convert-bt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) typedef int (*data_cmd_fn_t)(int argc, const char **argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct data_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) const char *summary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) data_cmd_fn_t fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static struct data_cmd data_cmds[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define for_each_cmd(cmd) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) for (cmd = data_cmds; cmd && cmd->name; cmd++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static const struct option data_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static const char * const data_subcommands[] = { "convert", NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static const char *data_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) "perf data [<common options>] <command> [<options>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static void print_usage(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct data_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) printf("Usage:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) printf("\t%s\n\n", data_usage[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) printf("\tAvailable commands:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) for_each_cmd(cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) printf("\t %s\t- %s\n", cmd->name, cmd->summary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static const char * const data_convert_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) "perf data convert [<options>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int cmd_data_convert(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) const char *to_ctf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct perf_data_convert_opts opts = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .force = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .all = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) const struct option options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) OPT_INCR('v', "verbose", &verbose, "be more verbose"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) OPT_STRING('i', "input", &input_name, "file", "input file name"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #ifdef HAVE_LIBBABELTRACE_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) OPT_BOOLEAN(0, "tod", &opts.tod, "Convert time to wall clock time"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #ifndef HAVE_LIBBABELTRACE_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pr_err("No conversion support compiled in. perf should be compiled with environment variables LIBBABELTRACE=1 and LIBBABELTRACE_DIR=/path/to/libbabeltrace/\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) argc = parse_options(argc, argv, options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) data_convert_usage, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) usage_with_options(data_convert_usage, options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (to_ctf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #ifdef HAVE_LIBBABELTRACE_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return bt_convert__perf2ctf(input_name, to_ctf, &opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) pr_err("The libbabeltrace support is not compiled in.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static struct data_cmd data_cmds[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) { "convert", "converts data file between formats", cmd_data_convert },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) { .name = NULL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int cmd_data(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct data_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) const char *cmdstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* No command specified. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (argc < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) goto usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) argc = parse_options_subcommand(argc, argv, data_options, data_subcommands, data_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) PARSE_OPT_STOP_AT_NON_OPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (argc < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) goto usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) cmdstr = argv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) for_each_cmd(cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (strcmp(cmd->name, cmdstr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return cmd->fn(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pr_err("Unknown command: %s\n", cmdstr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) print_usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }