From patchwork Thu Dec 21 15:25:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vladislav Valtchev (VMware)" X-Patchwork-Id: 10758367 Return-Path: linux-trace-devel-owner@vger.kernel.org Received: from mail-wr0-f194.google.com ([209.85.128.194]:43398 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751206AbdLUPZu (ORCPT ); Thu, 21 Dec 2017 10:25:50 -0500 From: "Vladislav Valtchev (VMware)" To: rostedt@goodmis.org Cc: y.karadz@gmail.com, linux-trace-devel@vger.kernel.org, linux-kernel@vger.kernel.org, "Vladislav Valtchev (VMware)" Subject: [PATCH v2 1/3] trace-cmd: Make read_proc() to return int status via OUT arg Date: Thu, 21 Dec 2017 17:25:18 +0200 Message-Id: <20171221152520.25867-2-vladislav.valtchev@gmail.com> In-Reply-To: <20171221152520.25867-1-vladislav.valtchev@gmail.com> References: <20171221152520.25867-1-vladislav.valtchev@gmail.com> Sender: linux-trace-devel-owner@vger.kernel.org List-ID: Content-Length: 4015 This patch changes both the implementation and the interface of read_proc() in trace-stack.c. First, it makes the function to read a string from the proc file and then parse it as an integer using strtol(). Then, it makes the function to return the integer read from the proc file using the int *status OUT parameter, in order to make possible its return value to be used by the caller to check if the operation succeeded. This new implementation relaxes the external contraints the function relies on, making it possible to be used by trace stat. The point is that 'stat' should not fail in case there is something wrong with the stack tracer. Only the call to die() in case the file is empty has been left in this patch: it will be removed as well in a separate commit. Signed-off-by: Vladislav Valtchev (VMware) --- trace-stack.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/trace-stack.c b/trace-stack.c index aa79ae3..c1058ca 100644 --- a/trace-stack.c +++ b/trace-stack.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -49,37 +50,79 @@ static void test_available(void) die("stack tracer not configured on running kernel"); } -static char read_proc(void) +/* + * Returns: + * -1 - Something went wrong + * 0 - File does not exist (stack tracer not enabled) + * 1 - Success + */ +static int read_proc(int *status) { - char buf[1]; + struct stat stat_buf; + char buf[64]; + long num; int fd; int n; + if (stat(PROC_FILE, &stat_buf) < 0) { + /* stack tracer not configured on running kernel */ + *status = 0; /* not configured means disabled */ + return 0; + } + fd = open(PROC_FILE, O_RDONLY); - if (fd < 0) - die("reading %s", PROC_FILE); - n = read(fd, buf, 1); - close(fd); - if (n != 1) + + if (fd < 0) { + /* we cannot open the file: likely a permission problem. */ + return -1; + } + + n = read(fd, buf, sizeof(buf)); + + /* We assume that the file is never empty we got no errors. */ + if (n <= 0) die("error reading %s", PROC_FILE); - return buf[0]; + /* Does this file have more than 63 characters?? */ + if (n >= sizeof(buf)) + return -1; + + /* n is guaranteed to be in the range [1, sizeof(buf)-1]. */ + buf[n] = 0; + close(fd); + + errno = 0; + + /* Read an integer from buf ignoring any non-digit trailing characters. */ + num = strtol(buf, NULL, 10); + + /* strtol() returned 0: we have to check for errors */ + if (!num && (errno == EINVAL || errno == ERANGE)) + return -1; + + if (num > INT_MAX || num < INT_MIN) + return -1; /* the number is good but does not fit in 'int' */ + + *status = num; + return 1; /* full success */ } -static void start_stop_trace(char val) +/* NOTE: this implementation only accepts new_status in the range [0..9]. */ +static void change_stack_tracer_status(int new_status) { char buf[1]; + int status; int fd; int n; - buf[0] = read_proc(); - if (buf[0] == val) - return; + if (read_proc(&status) > 0 && status == new_status) + return; /* nothing to do */ fd = open(PROC_FILE, O_WRONLY); + if (fd < 0) die("writing %s", PROC_FILE); - buf[0] = val; + buf[0] = new_status + '0'; n = write(fd, buf, 1); if (n < 0) die("writing into %s", PROC_FILE); @@ -88,12 +131,12 @@ static void start_stop_trace(char val) static void start_trace(void) { - start_stop_trace('1'); + change_stack_tracer_status(1); } static void stop_trace(void) { - start_stop_trace('0'); + change_stack_tracer_status(0); } static void reset_trace(void) @@ -123,8 +166,12 @@ static void read_trace(void) char *buf = NULL; size_t n; int r; + int status; - if (read_proc() == '1') + if (read_proc(&status) <= 0) + die("Invalid stack tracer state"); + + if (status > 0) printf("(stack tracer running)\n"); else printf("(stack tracer not running)\n"); From patchwork Thu Dec 21 15:25:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vladislav Valtchev (VMware)" X-Patchwork-Id: 10758365 Return-Path: linux-trace-devel-owner@vger.kernel.org Received: from mail-wr0-f195.google.com ([209.85.128.195]:43400 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750757AbdLUPZv (ORCPT ); Thu, 21 Dec 2017 10:25:51 -0500 From: "Vladislav Valtchev (VMware)" To: rostedt@goodmis.org Cc: y.karadz@gmail.com, linux-trace-devel@vger.kernel.org, linux-kernel@vger.kernel.org, "Vladislav Valtchev (VMware)" Subject: [PATCH v2 2/3] trace-cmd: Remove the die() call from read_proc() Date: Thu, 21 Dec 2017 17:25:19 +0200 Message-Id: <20171221152520.25867-3-vladislav.valtchev@gmail.com> In-Reply-To: <20171221152520.25867-1-vladislav.valtchev@gmail.com> References: <20171221152520.25867-1-vladislav.valtchev@gmail.com> Sender: linux-trace-devel-owner@vger.kernel.org List-ID: As trace-stack.c's read_proc() function is going to be used by trace-cmd stat, we don't want it to make the program die in case something went wrong. Therefore, this simple patch makes read_proc() to just return -1 in case the proc file was empty or read() failed with an error, instead of using die(). Signed-off-by: Vladislav Valtchev (VMware) --- trace-stack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trace-stack.c b/trace-stack.c index c1058ca..d55d994 100644 --- a/trace-stack.c +++ b/trace-stack.c @@ -79,9 +79,9 @@ static int read_proc(int *status) n = read(fd, buf, sizeof(buf)); - /* We assume that the file is never empty we got no errors. */ + /* The file was empty or read() failed with an error. */ if (n <= 0) - die("error reading %s", PROC_FILE); + return -1; /* Does this file have more than 63 characters?? */ if (n >= sizeof(buf)) From patchwork Thu Dec 21 15:25:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vladislav Valtchev (VMware)" X-Patchwork-Id: 10758363 Return-Path: linux-trace-devel-owner@vger.kernel.org Received: from mail-wr0-f194.google.com ([209.85.128.194]:44428 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751239AbdLUPZw (ORCPT ); Thu, 21 Dec 2017 10:25:52 -0500 From: "Vladislav Valtchev (VMware)" To: rostedt@goodmis.org Cc: y.karadz@gmail.com, linux-trace-devel@vger.kernel.org, linux-kernel@vger.kernel.org, "Vladislav Valtchev (VMware)" Subject: [PATCH v2 3/3] trace-cmd: Making stat to report when the stack tracer is ON Date: Thu, 21 Dec 2017 17:25:20 +0200 Message-Id: <20171221152520.25867-4-vladislav.valtchev@gmail.com> In-Reply-To: <20171221152520.25867-1-vladislav.valtchev@gmail.com> References: <20171221152520.25867-1-vladislav.valtchev@gmail.com> Sender: linux-trace-devel-owner@vger.kernel.org List-ID: Content-Length: 1981 trace-cmd stat is a handy way for users to see what tracing is currently going on, but currently it does not say anything about the stack tracing. This patch makes the command to show a message when the stack tracer is ON. Signed-off-by: Vladislav Valtchev (VMware) --- trace-cmd.h | 2 ++ trace-stack.c | 6 ++++++ trace-stat.c | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/trace-cmd.h b/trace-cmd.h index 6fd34d7..9704b2e 100644 --- a/trace-cmd.h +++ b/trace-cmd.h @@ -358,6 +358,8 @@ void tracecmd_free_hooks(struct hook_list *hooks); /* --- Hack! --- */ int tracecmd_blk_hack(struct tracecmd_input *handle); +/* --- Stack tracer functions --- */ +int tracecmd_stack_tracer_status(int *status); /* --- Debugging --- */ struct kbuffer *tracecmd_record_kbuf(struct tracecmd_input *handle, diff --git a/trace-stack.c b/trace-stack.c index d55d994..0028ecc 100644 --- a/trace-stack.c +++ b/trace-stack.c @@ -107,6 +107,12 @@ static int read_proc(int *status) return 1; /* full success */ } +/* Public wrapper of read_proc() */ +int tracecmd_stack_tracer_status(int *status) +{ + return read_proc(status); +} + /* NOTE: this implementation only accepts new_status in the range [0..9]. */ static void change_stack_tracer_status(int new_status) { diff --git a/trace-stat.c b/trace-stat.c index fd16354..61dd41f 100644 --- a/trace-stat.c +++ b/trace-stat.c @@ -894,6 +894,7 @@ void trace_stat (int argc, char **argv) struct buffer_instance *instance = &top_instance; int topt = 0; int c; + int stack_tracer_status; for (;;) { c = getopt(argc-1, argv+1, "tB:"); @@ -928,5 +929,12 @@ void trace_stat (int argc, char **argv) stat_instance(instance); } + if (tracecmd_stack_tracer_status(&stack_tracer_status) >= 0) { + if (stack_tracer_status > 0) + printf("Stack tracing is enabled\n\n"); + } else { + printf("The status of the stack tracer is indeterminate\n\n"); + } + exit(0); }