Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16ad2ffb authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

perf tools: Introduce perf_target__strerror()



The perf_target__strerror() sets @buf to a string that describes the
(perf_target-specific) error condition that is passed via @errnum.

This is similar to strerror_r() and does same thing if @errnum has a
standard errno value.

Signed-off-by: default avatarNamhyung Kim <namhyung.kim@lge.com>
Suggested-by: default avatarArnaldo Carvalho de Melo <acme@ghostprotocols.net>
Reviewed-by: default avatarDavid 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/1336367344-28071-6-git-send-email-namhyung.kim@lge.com


[ committer note: No need to use PERF_ERRNO_TARGET__SUCCESS, use shorter idiom ]
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent dfe78ada
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -831,6 +831,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
	struct perf_evsel *pos;
	struct perf_evlist *evsel_list;
	struct perf_record *rec = &record;
	char errbuf[BUFSIZ];

	perf_header__set_cmdline(argc, argv);

@@ -884,11 +885,24 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
		goto out_symbol_exit;
	}

	perf_target__validate(&rec->opts.target);
	err = perf_target__validate(&rec->opts.target);
	if (err) {
		perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
		ui__warning("%s", errbuf);
	}

	err = perf_target__parse_uid(&rec->opts.target);
	if (err) {
		int saved_errno = errno;

	if (perf_target__parse_uid(&rec->opts.target) < 0)
		perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
		ui__warning("%s", errbuf);

		err = -saved_errno;
		goto out_free_fd;
	}

	err = -ENOMEM;
	if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
		usage_with_options(record_usage, record_options);

+16 −3
Original line number Diff line number Diff line
@@ -1150,7 +1150,8 @@ static const char * const top_usage[] = {
int cmd_top(int argc, const char **argv, const char *prefix __used)
{
	struct perf_evsel *pos;
	int status = -ENOMEM;
	int status;
	char errbuf[BUFSIZ];
	struct perf_top top = {
		.count_filter	     = 5,
		.delay_secs	     = 2,
@@ -1252,10 +1253,22 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)

	setup_browser(false);

	perf_target__validate(&top.target);
	status = perf_target__validate(&top.target);
	if (status) {
		perf_target__strerror(&top.target, status, errbuf, BUFSIZ);
		ui__warning("%s", errbuf);
	}

	status = perf_target__parse_uid(&top.target);
	if (status) {
		int saved_errno = errno;

	if (perf_target__parse_uid(&top.target) < 0)
		perf_target__strerror(&top.target, status, errbuf, BUFSIZ);
		ui__warning("%s", errbuf);

		status = -saved_errno;
		goto out_delete_evlist;
	}

	if (top.target.tid == 0 && top.target.pid == 0 &&
	    top.target.uid_str == NULL)
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "event.h"
#include "debug.h"
#include "util.h"
#include "target.h"

int verbose;
bool dump_trace = false, quiet = false;
+51 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include "debug.h"

#include <pwd.h>
#include <string.h>


enum perf_target_errno perf_target__validate(struct perf_target *target)
@@ -89,3 +90,53 @@ enum perf_target_errno perf_target__parse_uid(struct perf_target *target)
	target->uid = result->pw_uid;
	return PERF_ERRNO_TARGET__SUCCESS;
}

/*
 * This must have a same ordering as the enum perf_target_errno.
 */
static const char *perf_target__error_str[] = {
	"PID/TID switch overriding CPU",
	"PID/TID switch overriding UID",
	"UID switch overriding CPU",
	"PID/TID switch overriding SYSTEM",
	"UID switch overriding SYSTEM",
	"Invalid User: %s",
	"Problems obtaining information for user %s",
};

int perf_target__strerror(struct perf_target *target, int errnum,
			  char *buf, size_t buflen)
{
	int idx;
	const char *msg;

	if (errnum >= 0) {
		strerror_r(errnum, buf, buflen);
		return 0;
	}

	if (errnum <  __PERF_ERRNO_TARGET__START ||
	    errnum >= __PERF_ERRNO_TARGET__END)
		return -1;

	idx = errnum - __PERF_ERRNO_TARGET__START;
	msg = perf_target__error_str[idx];

	switch (errnum) {
	case PERF_ERRNO_TARGET__PID_OVERRIDE_CPU
	 ... PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM:
		snprintf(buf, buflen, "%s", msg);
		break;

	case PERF_ERRNO_TARGET__INVALID_UID:
	case PERF_ERRNO_TARGET__USER_NOT_FOUND:
		snprintf(buf, buflen, msg, target->uid_str);
		break;

	default:
		/* cannot reach here */
		break;
	}

	return 0;
}
+3 −0
Original line number Diff line number Diff line
@@ -43,4 +43,7 @@ enum perf_target_errno {
enum perf_target_errno perf_target__validate(struct perf_target *target);
enum perf_target_errno perf_target__parse_uid(struct perf_target *target);

int perf_target__strerror(struct perf_target *target, int errnum, char *buf,
			  size_t buflen);

#endif /* _PERF_TARGET_H */