diff options
Diffstat (limited to 'tools/perf/util/util.c')
-rw-r--r-- | tools/perf/util/util.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index eeb83c80f458..391c1e928bd7 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -18,6 +18,7 @@ #include <linux/kernel.h> #include <linux/log2.h> #include <linux/time64.h> +#include <linux/overflow.h> #include <unistd.h> #include "cap.h" #include "strlist.h" @@ -200,7 +201,7 @@ static int rm_rf_depth_pat(const char *path, int depth, const char **pat) return rmdir(path); } -static int rm_rf_kcore_dir(const char *path) +static int rm_rf_a_kcore_dir(const char *path, const char *name) { char kcore_dir_path[PATH_MAX]; const char *pat[] = { @@ -210,11 +211,44 @@ static int rm_rf_kcore_dir(const char *path) NULL, }; - snprintf(kcore_dir_path, sizeof(kcore_dir_path), "%s/kcore_dir", path); + snprintf(kcore_dir_path, sizeof(kcore_dir_path), "%s/%s", path, name); return rm_rf_depth_pat(kcore_dir_path, 0, pat); } +static bool kcore_dir_filter(const char *name __maybe_unused, struct dirent *d) +{ + const char *pat[] = { + "kcore_dir", + "kcore_dir__[1-9]*", + NULL, + }; + + return match_pat(d->d_name, pat); +} + +static int rm_rf_kcore_dir(const char *path) +{ + struct strlist *kcore_dirs; + struct str_node *nd; + int ret; + + kcore_dirs = lsdir(path, kcore_dir_filter); + + if (!kcore_dirs) + return 0; + + strlist__for_each_entry(nd, kcore_dirs) { + ret = rm_rf_a_kcore_dir(path, nd->s); + if (ret) + return ret; + } + + strlist__delete(kcore_dirs); + + return 0; +} + int rm_rf_perf_data(const char *path) { const char *pat[] = { @@ -467,3 +501,35 @@ char *filename_with_chroot(int pid, const char *filename) return new_name; } + +/* + * Reallocate an array *arr of size *arr_sz so that it is big enough to contain + * x elements of size msz, initializing new entries to *init_val or zero if + * init_val is NULL + */ +int do_realloc_array_as_needed(void **arr, size_t *arr_sz, size_t x, size_t msz, const void *init_val) +{ + size_t new_sz = *arr_sz; + void *new_arr; + size_t i; + + if (!new_sz) + new_sz = msz >= 64 ? 1 : roundup(64, msz); /* Start with at least 64 bytes */ + while (x >= new_sz) { + if (check_mul_overflow(new_sz, (size_t)2, &new_sz)) + return -ENOMEM; + } + if (new_sz == *arr_sz) + return 0; + new_arr = calloc(new_sz, msz); + if (!new_arr) + return -ENOMEM; + memcpy(new_arr, *arr, *arr_sz * msz); + if (init_val) { + for (i = *arr_sz; i < new_sz; i++) + memcpy(new_arr + (i * msz), init_val, msz); + } + *arr = new_arr; + *arr_sz = new_sz; + return 0; +} |