summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Pihet <jean.pihet@linaro.org>2014-10-10 11:34:40 +0200
committerBorislav Petkov <bp@suse.de>2014-11-06 11:52:45 +0100
commit19642d6de57d41a70573269e4bcd0963ac707cda (patch)
tree113023e0c200cbda3441ca11c36c320e805c1d98
parentdbce5883da238f0da7302570058a45db7ab6a3ee (diff)
downloadrasd-19642d6de57d41a70573269e4bcd0963ac707cda.tar.gz
rasd: Parse config file for events to enable
The file 'rasd.cfg' is parsed for options: .the events to enable are stored line by line. The format is 'sys:name', .a line starting with '#' is a comment and is ignored, .a line full of spaces and/or tabs is empty and is ignored. Boris: rewrite cfg_valid_line() to use regex(3). We want to select only the "interesting" lines and ignore everything else. Signed-off-by: Jean Pihet <jean.pihet@linaro.org> Link: http://lkml.kernel.org/r/1412933690-25576-4-git-send-email-jean.pihet@linaro.org Signed-off-by: Borislav Petkov <bp@suse.de>
-rw-r--r--src/rasd.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/src/rasd.c b/src/rasd.c
index 9147d65..593e5b0 100644
--- a/src/rasd.c
+++ b/src/rasd.c
@@ -4,13 +4,37 @@
#include "ras.h"
#include "debugfs.h"
+#include <regex.h>
+
#define EVENT_STR_MAX_LENGTH 1024
#define SYS_NAME_SEPARATOR ":"
+#define RASD_CFG_FILE "rasd.cfg"
unsigned int page_size;
-struct perf_evlist evlist;
+struct perf_evlist *evlist;
struct perf_rasd rasd;
+/* Check if the read line is a valid config file line.*/
+static bool cfg_valid_line(char *str)
+{
+ regex_t reg;
+ int ret;
+
+ ret = regcomp(&reg, "^[:space:]*[a-z]+:[a-z_]+[:space:]*$",
+ REG_EXTENDED |
+ REG_NEWLINE); /* for matching $ */
+ if (ret)
+ err("compiling cfg regex");
+
+ ret = regexec(&reg, str, 0, NULL, 0);
+ if (ret) {
+ if (ret != REG_NOMATCH)
+ printf("error matching %s\n", str);
+ return false;
+ }
+ return true;
+}
+
/*
* Extract the event subsystem and event names from the command
* line argument. The syntax is 'sys:name'.
@@ -55,7 +79,38 @@ static int add_tp_event(char *event_str)
err("init tracepoint evsel");
/* Add the event to the lists of events */
- list_add_tail(&tp->node, &evlist.entries);
+ list_add_tail(&tp->node, &evlist->entries);
+
+ return ret;
+}
+
+/*
+ * Read the config file for events to enable
+ */
+static int read_config_file(void)
+{
+ FILE *file;
+ char *event_str;
+ int ret = 0;
+
+ file = fopen(RASD_CFG_FILE, "r");
+ if (!file)
+ return -ENODEV;
+
+ event_str = malloc(EVENT_STR_MAX_LENGTH);
+ if (!event_str)
+ return -ENOMEM;
+
+ /* Read config file, line by line */
+ while (fgets(event_str, EVENT_STR_MAX_LENGTH, file))
+ if (cfg_valid_line(event_str))
+ add_tp_event(event_str);
+
+ if (ferror(file))
+ ret = -EINVAL;
+
+ free(event_str);
+ fclose(file);
return ret;
}
@@ -63,7 +118,6 @@ static int add_tp_event(char *event_str)
int main()
{
struct perf_evsel *c;
- char *ev_name = strdup("mce:mce_record");
page_size = sysconf(_SC_PAGE_SIZE);
@@ -73,25 +127,29 @@ int main()
if (!debugfs_mount(NULL))
err("mounting debugfs");
- INIT_LIST_HEAD(&evlist.entries);
+ /* Initialize evlist */
+ evlist = perf_evlist__new();
+ if (!evlist)
+ err("allocating evlist");
- /* Add event from the name string */
- add_tp_event(ev_name);
+ /* Read config file */
+ if (read_config_file())
+ err("error reading config file");
- evlist__for_each(&evlist, c) {
+ evlist__for_each(evlist, c) {
/*
* On all online cpus by default.
*/
if (perf_evsel__open(c, cpu_map__new(NULL), NULL) < 0)
- err("opening counter");
+ err("opening tracepoint, are you root?");
}
- if (perf_evlist__mmap(&evlist, 4 /* opts->mmap_pages */, false) < 0)
- err("Failed to mmap with %d (%s)\n", errno, strerror(errno));
+ if (perf_evlist__mmap(evlist, 4 /* opts->mmap_pages */, false) < 0)
+ err("Failed to mmap with %d (%s)\n", errno, strerror(errno));
/* mmap it and all that, consume it */
- perf_evlist__delete(&evlist);
+ perf_evlist__delete(evlist);
free(rasd.name);
free(rasd.sys);