177 lines
3.2 KiB
C
177 lines
3.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2008, 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
|
|
*
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <getopt.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <sys/syscall.h>
|
|
|
|
#include "trace-local.h"
|
|
|
|
int silence_warnings;
|
|
int show_status;
|
|
|
|
#ifndef gettid
|
|
#define gettid() syscall(__NR_gettid)
|
|
#endif
|
|
|
|
void warning(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
if (silence_warnings)
|
|
return;
|
|
|
|
if (errno)
|
|
perror("trace-cmd");
|
|
errno = 0;
|
|
|
|
va_start(ap, fmt);
|
|
fprintf(stderr, " ");
|
|
vfprintf(stderr, fmt, ap);
|
|
va_end(ap);
|
|
|
|
fprintf(stderr, "\n");
|
|
}
|
|
|
|
void *malloc_or_die(unsigned int size)
|
|
{
|
|
void *data;
|
|
|
|
data = malloc(size);
|
|
if (!data)
|
|
die("malloc");
|
|
return data;
|
|
}
|
|
|
|
void tracecmd_debug(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
if (!tracecmd_get_debug())
|
|
return;
|
|
|
|
va_start(ap, fmt);
|
|
printf("[%d] ", (int)gettid());
|
|
vprintf(fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
static struct trace_log_severity {
|
|
int id;
|
|
const char *name;
|
|
} log_severity[] = {
|
|
{ .id = TEP_LOG_NONE, .name = "none" },
|
|
{ .id = TEP_LOG_CRITICAL, .name = "crit" },
|
|
{ .id = TEP_LOG_ERROR, .name = "err" },
|
|
{ .id = TEP_LOG_WARNING, .name = "warn" },
|
|
{ .id = TEP_LOG_INFO, .name = "info" },
|
|
{ .id = TEP_LOG_DEBUG, .name = "debug" },
|
|
{ .id = TEP_LOG_ALL, .name = "all" },
|
|
};
|
|
|
|
int trace_set_verbose(char *level)
|
|
{
|
|
int id;
|
|
|
|
/* Default level is info */
|
|
if (!level)
|
|
level = "info";
|
|
|
|
if (isdigit(level[0])) {
|
|
id = atoi(level);
|
|
if (id >= TEP_LOG_NONE) {
|
|
if (id > TEP_LOG_ALL)
|
|
id = TEP_LOG_ALL;
|
|
tracecmd_set_loglevel(id);
|
|
return 0;
|
|
}
|
|
} else {
|
|
int size = ARRAY_SIZE(log_severity);
|
|
int i;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
if (!strncmp(level, log_severity[i].name, strlen(log_severity[i].name))) {
|
|
tracecmd_set_loglevel(log_severity[i].id);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* struct command
|
|
* @name command name
|
|
* @run function to execute on command `name`
|
|
*/
|
|
struct command {
|
|
char *name;
|
|
void (*run)(int argc, char **argv);
|
|
};
|
|
|
|
|
|
/**
|
|
* Lookup table that maps command names to functions
|
|
*/
|
|
struct command commands[] = {
|
|
{"report", trace_report},
|
|
{"snapshot", trace_snapshot},
|
|
{"hist", trace_hist},
|
|
{"mem", trace_mem},
|
|
{"listen", trace_listen},
|
|
{"agent", trace_agent},
|
|
{"setup-guest", trace_setup_guest},
|
|
{"split", trace_split},
|
|
{"restore", trace_restore},
|
|
{"stack", trace_stack},
|
|
{"check-events", trace_check_events},
|
|
{"record", trace_record},
|
|
{"start", trace_start},
|
|
{"set", trace_set},
|
|
{"extract", trace_extract},
|
|
{"stop", trace_stop},
|
|
{"stream", trace_stream},
|
|
{"profile", trace_profile},
|
|
{"restart", trace_restart},
|
|
{"clear", trace_clear},
|
|
{"reset", trace_reset},
|
|
{"stat", trace_stat},
|
|
{"options", trace_option},
|
|
{"show", trace_show},
|
|
{"list", trace_list},
|
|
{"help", trace_usage},
|
|
{"dump", trace_dump},
|
|
{"convert", trace_convert},
|
|
{"-h", trace_usage},
|
|
};
|
|
|
|
int main (int argc, char **argv)
|
|
{
|
|
int i;
|
|
|
|
errno = 0;
|
|
|
|
if (argc < 2)
|
|
trace_usage(argc, argv);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(commands); ++i) {
|
|
if (strcmp(argv[1], commands[i].name) == 0 ){
|
|
commands[i].run(argc, argv);
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
/* No valid command found, show help */
|
|
trace_usage(argc, argv);
|
|
out:
|
|
exit(0);
|
|
}
|