Messages in this thread Patch in this message | | | From | Jiri Olsa <> | Subject | [PATCH 08/14] perf data: Add directory support | Date | Sun, 3 Feb 2019 16:30:12 +0100 |
| |
Adding support to have directory as perf.data.
The caller needs to set 'struct perf_data::is_dir flag and the path will be treated as directory.
The 'struct perf_data::file' is initialized and open as 'path/header' file.
Adding check to direcory interface functions to check on is_dir flag.
Link: http://lkml.kernel.org/n/tip-pvot1aywiem9epgqpfi1agaj@git.kernel.org Signed-off-by: Jiri Olsa <jolsa@kernel.org> --- tools/perf/util/data.c | 39 +++++++++++++++++++++++++++++++++++++-- tools/perf/util/data.h | 6 ++++++ 2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 7c37b67fbc3c..59c052454fac 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -34,6 +34,9 @@ int perf_data__create_dir(struct perf_data *data, int nr) struct perf_data_file *files = NULL; int i, ret = -1; + if (WARN_ON(!data->is_dir)) + return -EINVAL; + files = malloc(nr * sizeof(*files)); if (!files) return -ENOMEM; @@ -61,7 +64,6 @@ int perf_data__create_dir(struct perf_data *data, int nr) return ret; } -__maybe_unused static int perf_data__open_dir(struct perf_data *data) { struct perf_data_file *files = NULL; @@ -70,6 +72,9 @@ static int perf_data__open_dir(struct perf_data *data) DIR *dir; int nr = 0; + if (WARN_ON(!data->is_dir)) + return -EINVAL; + dir = opendir(data->path); if (!dir) return -EINVAL; @@ -159,6 +164,16 @@ static int check_backup(struct perf_data *data) return 0; } +static bool is_dir(struct perf_data *data) +{ + struct stat st; + + if (stat(data->path, &st)) + return false; + + return (st.st_mode & S_IFMT) == S_IFDIR; +} + static int open_file_read(struct perf_data *data) { struct stat st; @@ -240,6 +255,22 @@ static int open_file_dup(struct perf_data *data) return open_file(data); } +static int open_dir(struct perf_data *data) +{ + if (perf_data__is_write(data)) { + if (mkdir(data->path, S_IRWXU) < 0) + return -1; + } else { + if (perf_data__open_dir(data)) + return -1; + } + + if (asprintf(&data->file.path, "%s/header", data->path) < 0) + return -ENOMEM; + + return open_file(data); +} + int perf_data__open(struct perf_data *data) { if (check_pipe(data)) @@ -251,7 +282,11 @@ int perf_data__open(struct perf_data *data) if (check_backup(data)) return -1; - return open_file_dup(data); + if (perf_data__is_read(data)) + data->is_dir = is_dir(data); + + return perf_data__is_dir(data) ? + open_dir(data) : open_file_dup(data); } void perf_data__close(struct perf_data *data) diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h index 3b4115dc777f..a1edf7e03a71 100644 --- a/tools/perf/util/data.h +++ b/tools/perf/util/data.h @@ -19,6 +19,7 @@ struct perf_data { const char *path; struct perf_data_file file; bool is_pipe; + bool is_dir; bool force; enum perf_data_mode mode; @@ -43,6 +44,11 @@ static inline int perf_data__is_pipe(struct perf_data *data) return data->is_pipe; } +static inline bool perf_data__is_dir(struct perf_data *data) +{ + return data->is_dir; +} + static inline int perf_data__fd(struct perf_data *data) { return data->file.fd; -- 2.17.2
| |