mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-29 15:43:59 +08:00
770a34a38b
There were some combinations of these switches that are not so appropriate IMHO. Since there are implicit priorities between them and they worked well anyway, but it ends up opening useless duplicated events. For example, 'perf stat -t <pid> -a' will open multiple events for the thread instead of one. Add explicit checks and warn user in perf_target__validate(). Signed-off-by: Namhyung Kim <namhyung.kim@lge.com> Reviewed-by: David Ahern <dsahern@gmail.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1335417327-11796-7-git-send-email-namhyung.kim@lge.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
150 lines
3.1 KiB
C
150 lines
3.1 KiB
C
/*
|
|
* usage.c
|
|
*
|
|
* Various reporting routines.
|
|
* Originally copied from GIT source.
|
|
*
|
|
* Copyright (C) Linus Torvalds, 2005
|
|
*/
|
|
#include "util.h"
|
|
#include "debug.h"
|
|
|
|
static void report(const char *prefix, const char *err, va_list params)
|
|
{
|
|
char msg[1024];
|
|
vsnprintf(msg, sizeof(msg), err, params);
|
|
fprintf(stderr, " %s%s\n", prefix, msg);
|
|
}
|
|
|
|
static NORETURN void usage_builtin(const char *err)
|
|
{
|
|
fprintf(stderr, "\n Usage: %s\n", err);
|
|
exit(129);
|
|
}
|
|
|
|
static NORETURN void die_builtin(const char *err, va_list params)
|
|
{
|
|
report(" Fatal: ", err, params);
|
|
exit(128);
|
|
}
|
|
|
|
static void error_builtin(const char *err, va_list params)
|
|
{
|
|
report(" Error: ", err, params);
|
|
}
|
|
|
|
static void warn_builtin(const char *warn, va_list params)
|
|
{
|
|
report(" Warning: ", warn, params);
|
|
}
|
|
|
|
/* If we are in a dlopen()ed .so write to a global variable would segfault
|
|
* (ugh), so keep things static. */
|
|
static void (*usage_routine)(const char *err) NORETURN = usage_builtin;
|
|
static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;
|
|
static void (*error_routine)(const char *err, va_list params) = error_builtin;
|
|
static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
|
|
|
|
void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN)
|
|
{
|
|
die_routine = routine;
|
|
}
|
|
|
|
void usage(const char *err)
|
|
{
|
|
usage_routine(err);
|
|
}
|
|
|
|
void die(const char *err, ...)
|
|
{
|
|
va_list params;
|
|
|
|
va_start(params, err);
|
|
die_routine(err, params);
|
|
va_end(params);
|
|
}
|
|
|
|
int error(const char *err, ...)
|
|
{
|
|
va_list params;
|
|
|
|
va_start(params, err);
|
|
error_routine(err, params);
|
|
va_end(params);
|
|
return -1;
|
|
}
|
|
|
|
void warning(const char *warn, ...)
|
|
{
|
|
va_list params;
|
|
|
|
va_start(params, warn);
|
|
warn_routine(warn, params);
|
|
va_end(params);
|
|
}
|
|
|
|
uid_t parse_target_uid(const char *str)
|
|
{
|
|
struct passwd pwd, *result;
|
|
char buf[1024];
|
|
|
|
if (str == NULL)
|
|
return UINT_MAX;
|
|
|
|
getpwnam_r(str, &pwd, buf, sizeof(buf), &result);
|
|
|
|
if (result == NULL) {
|
|
char *endptr;
|
|
int uid = strtol(str, &endptr, 10);
|
|
|
|
if (*endptr != '\0') {
|
|
ui__error("Invalid user %s\n", str);
|
|
return UINT_MAX - 1;
|
|
}
|
|
|
|
getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
|
|
|
|
if (result == NULL) {
|
|
ui__error("Problems obtaining information for user %s\n",
|
|
str);
|
|
return UINT_MAX - 1;
|
|
}
|
|
}
|
|
|
|
return result->pw_uid;
|
|
}
|
|
|
|
void perf_target__validate(struct perf_target *target)
|
|
{
|
|
if (target->pid)
|
|
target->tid = target->pid;
|
|
|
|
/* CPU and PID are mutually exclusive */
|
|
if (target->tid && target->cpu_list) {
|
|
ui__warning("WARNING: PID switch overriding CPU\n");
|
|
sleep(1);
|
|
target->cpu_list = NULL;
|
|
}
|
|
|
|
/* UID and PID are mutually exclusive */
|
|
if (target->tid && target->uid_str) {
|
|
ui__warning("PID/TID switch overriding UID\n");
|
|
sleep(1);
|
|
target->uid_str = NULL;
|
|
}
|
|
|
|
/* UID and CPU are mutually exclusive */
|
|
if (target->uid_str && target->cpu_list) {
|
|
ui__warning("UID switch overriding CPU\n");
|
|
sleep(1);
|
|
target->cpu_list = NULL;
|
|
}
|
|
|
|
/* PID/UID and SYSTEM are mutually exclusive */
|
|
if ((target->tid || target->uid_str) && target->system_wide) {
|
|
ui__warning("PID/TID/UID switch overriding CPU\n");
|
|
sleep(1);
|
|
target->system_wide = false;
|
|
}
|
|
}
|