Merge tag 'hwmon-for-linus-v4.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / tools / perf / util / probe-file.c
1 /*
2  * probe-file.c : operate ftrace k/uprobe events files
3  *
4  * Written by Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 #include <sys/uio.h>
18 #include "util.h"
19 #include "event.h"
20 #include "strlist.h"
21 #include "debug.h"
22 #include "cache.h"
23 #include "color.h"
24 #include "symbol.h"
25 #include "thread.h"
26 #include <api/fs/tracing_path.h>
27 #include "probe-event.h"
28 #include "probe-file.h"
29 #include "session.h"
30
31 #define MAX_CMDLEN 256
32
33 static void print_open_warning(int err, bool uprobe)
34 {
35         char sbuf[STRERR_BUFSIZE];
36
37         if (err == -ENOENT) {
38                 const char *config;
39
40                 if (uprobe)
41                         config = "CONFIG_UPROBE_EVENTS";
42                 else
43                         config = "CONFIG_KPROBE_EVENTS";
44
45                 pr_warning("%cprobe_events file does not exist"
46                            " - please rebuild kernel with %s.\n",
47                            uprobe ? 'u' : 'k', config);
48         } else if (err == -ENOTSUP)
49                 pr_warning("Tracefs or debugfs is not mounted.\n");
50         else
51                 pr_warning("Failed to open %cprobe_events: %s\n",
52                            uprobe ? 'u' : 'k',
53                            str_error_r(-err, sbuf, sizeof(sbuf)));
54 }
55
56 static void print_both_open_warning(int kerr, int uerr)
57 {
58         /* Both kprobes and uprobes are disabled, warn it. */
59         if (kerr == -ENOTSUP && uerr == -ENOTSUP)
60                 pr_warning("Tracefs or debugfs is not mounted.\n");
61         else if (kerr == -ENOENT && uerr == -ENOENT)
62                 pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS "
63                            "or/and CONFIG_UPROBE_EVENTS.\n");
64         else {
65                 char sbuf[STRERR_BUFSIZE];
66                 pr_warning("Failed to open kprobe events: %s.\n",
67                            str_error_r(-kerr, sbuf, sizeof(sbuf)));
68                 pr_warning("Failed to open uprobe events: %s.\n",
69                            str_error_r(-uerr, sbuf, sizeof(sbuf)));
70         }
71 }
72
73 static int open_probe_events(const char *trace_file, bool readwrite)
74 {
75         char buf[PATH_MAX];
76         const char *tracing_dir = "";
77         int ret;
78
79         ret = e_snprintf(buf, PATH_MAX, "%s/%s%s",
80                          tracing_path, tracing_dir, trace_file);
81         if (ret >= 0) {
82                 pr_debug("Opening %s write=%d\n", buf, readwrite);
83                 if (readwrite && !probe_event_dry_run)
84                         ret = open(buf, O_RDWR | O_APPEND, 0);
85                 else
86                         ret = open(buf, O_RDONLY, 0);
87
88                 if (ret < 0)
89                         ret = -errno;
90         }
91         return ret;
92 }
93
94 static int open_kprobe_events(bool readwrite)
95 {
96         return open_probe_events("kprobe_events", readwrite);
97 }
98
99 static int open_uprobe_events(bool readwrite)
100 {
101         return open_probe_events("uprobe_events", readwrite);
102 }
103
104 int probe_file__open(int flag)
105 {
106         int fd;
107
108         if (flag & PF_FL_UPROBE)
109                 fd = open_uprobe_events(flag & PF_FL_RW);
110         else
111                 fd = open_kprobe_events(flag & PF_FL_RW);
112         if (fd < 0)
113                 print_open_warning(fd, flag & PF_FL_UPROBE);
114
115         return fd;
116 }
117
118 int probe_file__open_both(int *kfd, int *ufd, int flag)
119 {
120         if (!kfd || !ufd)
121                 return -EINVAL;
122
123         *kfd = open_kprobe_events(flag & PF_FL_RW);
124         *ufd = open_uprobe_events(flag & PF_FL_RW);
125         if (*kfd < 0 && *ufd < 0) {
126                 print_both_open_warning(*kfd, *ufd);
127                 return *kfd;
128         }
129
130         return 0;
131 }
132
133 /* Get raw string list of current kprobe_events  or uprobe_events */
134 struct strlist *probe_file__get_rawlist(int fd)
135 {
136         int ret, idx, fddup;
137         FILE *fp;
138         char buf[MAX_CMDLEN];
139         char *p;
140         struct strlist *sl;
141
142         if (fd < 0)
143                 return NULL;
144
145         sl = strlist__new(NULL, NULL);
146         if (sl == NULL)
147                 return NULL;
148
149         fddup = dup(fd);
150         if (fddup < 0)
151                 goto out_free_sl;
152
153         fp = fdopen(fddup, "r");
154         if (!fp)
155                 goto out_close_fddup;
156
157         while (!feof(fp)) {
158                 p = fgets(buf, MAX_CMDLEN, fp);
159                 if (!p)
160                         break;
161
162                 idx = strlen(p) - 1;
163                 if (p[idx] == '\n')
164                         p[idx] = '\0';
165                 ret = strlist__add(sl, buf);
166                 if (ret < 0) {
167                         pr_debug("strlist__add failed (%d)\n", ret);
168                         goto out_close_fp;
169                 }
170         }
171         fclose(fp);
172
173         return sl;
174
175 out_close_fp:
176         fclose(fp);
177         goto out_free_sl;
178 out_close_fddup:
179         close(fddup);
180 out_free_sl:
181         strlist__delete(sl);
182         return NULL;
183 }
184
185 static struct strlist *__probe_file__get_namelist(int fd, bool include_group)
186 {
187         char buf[128];
188         struct strlist *sl, *rawlist;
189         struct str_node *ent;
190         struct probe_trace_event tev;
191         int ret = 0;
192
193         memset(&tev, 0, sizeof(tev));
194         rawlist = probe_file__get_rawlist(fd);
195         if (!rawlist)
196                 return NULL;
197         sl = strlist__new(NULL, NULL);
198         strlist__for_each_entry(ent, rawlist) {
199                 ret = parse_probe_trace_command(ent->s, &tev);
200                 if (ret < 0)
201                         break;
202                 if (include_group) {
203                         ret = e_snprintf(buf, 128, "%s:%s", tev.group,
204                                         tev.event);
205                         if (ret >= 0)
206                                 ret = strlist__add(sl, buf);
207                 } else
208                         ret = strlist__add(sl, tev.event);
209                 clear_probe_trace_event(&tev);
210                 if (ret < 0)
211                         break;
212         }
213         strlist__delete(rawlist);
214
215         if (ret < 0) {
216                 strlist__delete(sl);
217                 return NULL;
218         }
219         return sl;
220 }
221
222 /* Get current perf-probe event names */
223 struct strlist *probe_file__get_namelist(int fd)
224 {
225         return __probe_file__get_namelist(fd, false);
226 }
227
228 int probe_file__add_event(int fd, struct probe_trace_event *tev)
229 {
230         int ret = 0;
231         char *buf = synthesize_probe_trace_command(tev);
232         char sbuf[STRERR_BUFSIZE];
233
234         if (!buf) {
235                 pr_debug("Failed to synthesize probe trace event.\n");
236                 return -EINVAL;
237         }
238
239         pr_debug("Writing event: %s\n", buf);
240         if (!probe_event_dry_run) {
241                 if (write(fd, buf, strlen(buf)) < (int)strlen(buf)) {
242                         ret = -errno;
243                         pr_warning("Failed to write event: %s\n",
244                                    str_error_r(errno, sbuf, sizeof(sbuf)));
245                 }
246         }
247         free(buf);
248
249         return ret;
250 }
251
252 static int __del_trace_probe_event(int fd, struct str_node *ent)
253 {
254         char *p;
255         char buf[128];
256         int ret;
257
258         /* Convert from perf-probe event to trace-probe event */
259         ret = e_snprintf(buf, 128, "-:%s", ent->s);
260         if (ret < 0)
261                 goto error;
262
263         p = strchr(buf + 2, ':');
264         if (!p) {
265                 pr_debug("Internal error: %s should have ':' but not.\n",
266                          ent->s);
267                 ret = -ENOTSUP;
268                 goto error;
269         }
270         *p = '/';
271
272         pr_debug("Writing event: %s\n", buf);
273         ret = write(fd, buf, strlen(buf));
274         if (ret < 0) {
275                 ret = -errno;
276                 goto error;
277         }
278
279         return 0;
280 error:
281         pr_warning("Failed to delete event: %s\n",
282                    str_error_r(-ret, buf, sizeof(buf)));
283         return ret;
284 }
285
286 int probe_file__get_events(int fd, struct strfilter *filter,
287                            struct strlist *plist)
288 {
289         struct strlist *namelist;
290         struct str_node *ent;
291         const char *p;
292         int ret = -ENOENT;
293
294         if (!plist)
295                 return -EINVAL;
296
297         namelist = __probe_file__get_namelist(fd, true);
298         if (!namelist)
299                 return -ENOENT;
300
301         strlist__for_each_entry(ent, namelist) {
302                 p = strchr(ent->s, ':');
303                 if ((p && strfilter__compare(filter, p + 1)) ||
304                     strfilter__compare(filter, ent->s)) {
305                         strlist__add(plist, ent->s);
306                         ret = 0;
307                 }
308         }
309         strlist__delete(namelist);
310
311         return ret;
312 }
313
314 int probe_file__del_strlist(int fd, struct strlist *namelist)
315 {
316         int ret = 0;
317         struct str_node *ent;
318
319         strlist__for_each_entry(ent, namelist) {
320                 ret = __del_trace_probe_event(fd, ent);
321                 if (ret < 0)
322                         break;
323         }
324         return ret;
325 }
326
327 int probe_file__del_events(int fd, struct strfilter *filter)
328 {
329         struct strlist *namelist;
330         int ret;
331
332         namelist = strlist__new(NULL, NULL);
333         if (!namelist)
334                 return -ENOMEM;
335
336         ret = probe_file__get_events(fd, filter, namelist);
337         if (ret < 0)
338                 return ret;
339
340         ret = probe_file__del_strlist(fd, namelist);
341         strlist__delete(namelist);
342
343         return ret;
344 }
345
346 /* Caller must ensure to remove this entry from list */
347 static void probe_cache_entry__delete(struct probe_cache_entry *entry)
348 {
349         if (entry) {
350                 BUG_ON(!list_empty(&entry->node));
351
352                 strlist__delete(entry->tevlist);
353                 clear_perf_probe_event(&entry->pev);
354                 zfree(&entry->spev);
355                 free(entry);
356         }
357 }
358
359 static struct probe_cache_entry *
360 probe_cache_entry__new(struct perf_probe_event *pev)
361 {
362         struct probe_cache_entry *entry = zalloc(sizeof(*entry));
363
364         if (entry) {
365                 INIT_LIST_HEAD(&entry->node);
366                 entry->tevlist = strlist__new(NULL, NULL);
367                 if (!entry->tevlist)
368                         zfree(&entry);
369                 else if (pev) {
370                         entry->spev = synthesize_perf_probe_command(pev);
371                         if (!entry->spev ||
372                             perf_probe_event__copy(&entry->pev, pev) < 0) {
373                                 probe_cache_entry__delete(entry);
374                                 return NULL;
375                         }
376                 }
377         }
378
379         return entry;
380 }
381
382 int probe_cache_entry__get_event(struct probe_cache_entry *entry,
383                                  struct probe_trace_event **tevs)
384 {
385         struct probe_trace_event *tev;
386         struct str_node *node;
387         int ret, i;
388
389         ret = strlist__nr_entries(entry->tevlist);
390         if (ret > probe_conf.max_probes)
391                 return -E2BIG;
392
393         *tevs = zalloc(ret * sizeof(*tev));
394         if (!*tevs)
395                 return -ENOMEM;
396
397         i = 0;
398         strlist__for_each_entry(node, entry->tevlist) {
399                 tev = &(*tevs)[i++];
400                 ret = parse_probe_trace_command(node->s, tev);
401                 if (ret < 0)
402                         break;
403         }
404         return i;
405 }
406
407 /* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */
408 static int probe_cache__open(struct probe_cache *pcache, const char *target)
409 {
410         char cpath[PATH_MAX];
411         char sbuildid[SBUILD_ID_SIZE];
412         char *dir_name = NULL;
413         bool is_kallsyms = false;
414         int ret, fd;
415
416         if (target && build_id_cache__cached(target)) {
417                 /* This is a cached buildid */
418                 strncpy(sbuildid, target, SBUILD_ID_SIZE);
419                 dir_name = build_id_cache__linkname(sbuildid, NULL, 0);
420                 goto found;
421         }
422
423         if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) {
424                 target = DSO__NAME_KALLSYMS;
425                 is_kallsyms = true;
426                 ret = sysfs__sprintf_build_id("/", sbuildid);
427         } else
428                 ret = filename__sprintf_build_id(target, sbuildid);
429
430         if (ret < 0) {
431                 pr_debug("Failed to get build-id from %s.\n", target);
432                 return ret;
433         }
434
435         /* If we have no buildid cache, make it */
436         if (!build_id_cache__cached(sbuildid)) {
437                 ret = build_id_cache__add_s(sbuildid, target,
438                                             is_kallsyms, NULL);
439                 if (ret < 0) {
440                         pr_debug("Failed to add build-id cache: %s\n", target);
441                         return ret;
442                 }
443         }
444
445         dir_name = build_id_cache__cachedir(sbuildid, target, is_kallsyms,
446                                             false);
447 found:
448         if (!dir_name) {
449                 pr_debug("Failed to get cache from %s\n", target);
450                 return -ENOMEM;
451         }
452
453         snprintf(cpath, PATH_MAX, "%s/probes", dir_name);
454         fd = open(cpath, O_CREAT | O_RDWR, 0644);
455         if (fd < 0)
456                 pr_debug("Failed to open cache(%d): %s\n", fd, cpath);
457         free(dir_name);
458         pcache->fd = fd;
459
460         return fd;
461 }
462
463 static int probe_cache__load(struct probe_cache *pcache)
464 {
465         struct probe_cache_entry *entry = NULL;
466         char buf[MAX_CMDLEN], *p;
467         int ret = 0, fddup;
468         FILE *fp;
469
470         fddup = dup(pcache->fd);
471         if (fddup < 0)
472                 return -errno;
473         fp = fdopen(fddup, "r");
474         if (!fp) {
475                 close(fddup);
476                 return -EINVAL;
477         }
478
479         while (!feof(fp)) {
480                 if (!fgets(buf, MAX_CMDLEN, fp))
481                         break;
482                 p = strchr(buf, '\n');
483                 if (p)
484                         *p = '\0';
485                 /* #perf_probe_event or %sdt_event */
486                 if (buf[0] == '#' || buf[0] == '%') {
487                         entry = probe_cache_entry__new(NULL);
488                         if (!entry) {
489                                 ret = -ENOMEM;
490                                 goto out;
491                         }
492                         if (buf[0] == '%')
493                                 entry->sdt = true;
494                         entry->spev = strdup(buf + 1);
495                         if (entry->spev)
496                                 ret = parse_perf_probe_command(buf + 1,
497                                                                 &entry->pev);
498                         else
499                                 ret = -ENOMEM;
500                         if (ret < 0) {
501                                 probe_cache_entry__delete(entry);
502                                 goto out;
503                         }
504                         list_add_tail(&entry->node, &pcache->entries);
505                 } else {        /* trace_probe_event */
506                         if (!entry) {
507                                 ret = -EINVAL;
508                                 goto out;
509                         }
510                         strlist__add(entry->tevlist, buf);
511                 }
512         }
513 out:
514         fclose(fp);
515         return ret;
516 }
517
518 static struct probe_cache *probe_cache__alloc(void)
519 {
520         struct probe_cache *pcache = zalloc(sizeof(*pcache));
521
522         if (pcache) {
523                 INIT_LIST_HEAD(&pcache->entries);
524                 pcache->fd = -EINVAL;
525         }
526         return pcache;
527 }
528
529 void probe_cache__purge(struct probe_cache *pcache)
530 {
531         struct probe_cache_entry *entry, *n;
532
533         list_for_each_entry_safe(entry, n, &pcache->entries, node) {
534                 list_del_init(&entry->node);
535                 probe_cache_entry__delete(entry);
536         }
537 }
538
539 void probe_cache__delete(struct probe_cache *pcache)
540 {
541         if (!pcache)
542                 return;
543
544         probe_cache__purge(pcache);
545         if (pcache->fd > 0)
546                 close(pcache->fd);
547         free(pcache);
548 }
549
550 struct probe_cache *probe_cache__new(const char *target)
551 {
552         struct probe_cache *pcache = probe_cache__alloc();
553         int ret;
554
555         if (!pcache)
556                 return NULL;
557
558         ret = probe_cache__open(pcache, target);
559         if (ret < 0) {
560                 pr_debug("Cache open error: %d\n", ret);
561                 goto out_err;
562         }
563
564         ret = probe_cache__load(pcache);
565         if (ret < 0) {
566                 pr_debug("Cache read error: %d\n", ret);
567                 goto out_err;
568         }
569
570         return pcache;
571
572 out_err:
573         probe_cache__delete(pcache);
574         return NULL;
575 }
576
577 static bool streql(const char *a, const char *b)
578 {
579         if (a == b)
580                 return true;
581
582         if (!a || !b)
583                 return false;
584
585         return !strcmp(a, b);
586 }
587
588 struct probe_cache_entry *
589 probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
590 {
591         struct probe_cache_entry *entry = NULL;
592         char *cmd = synthesize_perf_probe_command(pev);
593
594         if (!cmd)
595                 return NULL;
596
597         for_each_probe_cache_entry(entry, pcache) {
598                 if (pev->sdt) {
599                         if (entry->pev.event &&
600                             streql(entry->pev.event, pev->event) &&
601                             (!pev->group ||
602                              streql(entry->pev.group, pev->group)))
603                                 goto found;
604
605                         continue;
606                 }
607                 /* Hit if same event name or same command-string */
608                 if ((pev->event &&
609                      (streql(entry->pev.group, pev->group) &&
610                       streql(entry->pev.event, pev->event))) ||
611                     (!strcmp(entry->spev, cmd)))
612                         goto found;
613         }
614         entry = NULL;
615
616 found:
617         free(cmd);
618         return entry;
619 }
620
621 struct probe_cache_entry *
622 probe_cache__find_by_name(struct probe_cache *pcache,
623                           const char *group, const char *event)
624 {
625         struct probe_cache_entry *entry = NULL;
626
627         for_each_probe_cache_entry(entry, pcache) {
628                 /* Hit if same event name or same command-string */
629                 if (streql(entry->pev.group, group) &&
630                     streql(entry->pev.event, event))
631                         goto found;
632         }
633         entry = NULL;
634
635 found:
636         return entry;
637 }
638
639 int probe_cache__add_entry(struct probe_cache *pcache,
640                            struct perf_probe_event *pev,
641                            struct probe_trace_event *tevs, int ntevs)
642 {
643         struct probe_cache_entry *entry = NULL;
644         char *command;
645         int i, ret = 0;
646
647         if (!pcache || !pev || !tevs || ntevs <= 0) {
648                 ret = -EINVAL;
649                 goto out_err;
650         }
651
652         /* Remove old cache entry */
653         entry = probe_cache__find(pcache, pev);
654         if (entry) {
655                 list_del_init(&entry->node);
656                 probe_cache_entry__delete(entry);
657         }
658
659         ret = -ENOMEM;
660         entry = probe_cache_entry__new(pev);
661         if (!entry)
662                 goto out_err;
663
664         for (i = 0; i < ntevs; i++) {
665                 if (!tevs[i].point.symbol)
666                         continue;
667
668                 command = synthesize_probe_trace_command(&tevs[i]);
669                 if (!command)
670                         goto out_err;
671                 strlist__add(entry->tevlist, command);
672                 free(command);
673         }
674         list_add_tail(&entry->node, &pcache->entries);
675         pr_debug("Added probe cache: %d\n", ntevs);
676         return 0;
677
678 out_err:
679         pr_debug("Failed to add probe caches\n");
680         probe_cache_entry__delete(entry);
681         return ret;
682 }
683
684 #ifdef HAVE_GELF_GETNOTE_SUPPORT
685 static unsigned long long sdt_note__get_addr(struct sdt_note *note)
686 {
687         return note->bit32 ? (unsigned long long)note->addr.a32[0]
688                  : (unsigned long long)note->addr.a64[0];
689 }
690
691 int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname)
692 {
693         struct probe_cache_entry *entry = NULL;
694         struct list_head sdtlist;
695         struct sdt_note *note;
696         char *buf;
697         char sdtgrp[64];
698         int ret;
699
700         INIT_LIST_HEAD(&sdtlist);
701         ret = get_sdt_note_list(&sdtlist, pathname);
702         if (ret < 0) {
703                 pr_debug("Failed to get sdt note: %d\n", ret);
704                 return ret;
705         }
706         list_for_each_entry(note, &sdtlist, note_list) {
707                 ret = snprintf(sdtgrp, 64, "sdt_%s", note->provider);
708                 if (ret < 0)
709                         break;
710                 /* Try to find same-name entry */
711                 entry = probe_cache__find_by_name(pcache, sdtgrp, note->name);
712                 if (!entry) {
713                         entry = probe_cache_entry__new(NULL);
714                         if (!entry) {
715                                 ret = -ENOMEM;
716                                 break;
717                         }
718                         entry->sdt = true;
719                         ret = asprintf(&entry->spev, "%s:%s=%s", sdtgrp,
720                                         note->name, note->name);
721                         if (ret < 0)
722                                 break;
723                         entry->pev.event = strdup(note->name);
724                         entry->pev.group = strdup(sdtgrp);
725                         list_add_tail(&entry->node, &pcache->entries);
726                 }
727                 ret = asprintf(&buf, "p:%s/%s %s:0x%llx",
728                                 sdtgrp, note->name, pathname,
729                                 sdt_note__get_addr(note));
730                 if (ret < 0)
731                         break;
732                 strlist__add(entry->tevlist, buf);
733                 free(buf);
734                 entry = NULL;
735         }
736         if (entry) {
737                 list_del_init(&entry->node);
738                 probe_cache_entry__delete(entry);
739         }
740         cleanup_sdt_note_list(&sdtlist);
741         return ret;
742 }
743 #endif
744
745 static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd)
746 {
747         struct str_node *snode;
748         struct stat st;
749         struct iovec iov[3];
750         const char *prefix = entry->sdt ? "%" : "#";
751         int ret;
752         /* Save stat for rollback */
753         ret = fstat(fd, &st);
754         if (ret < 0)
755                 return ret;
756
757         pr_debug("Writing cache: %s%s\n", prefix, entry->spev);
758         iov[0].iov_base = (void *)prefix; iov[0].iov_len = 1;
759         iov[1].iov_base = entry->spev; iov[1].iov_len = strlen(entry->spev);
760         iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1;
761         ret = writev(fd, iov, 3);
762         if (ret < (int)iov[1].iov_len + 2)
763                 goto rollback;
764
765         strlist__for_each_entry(snode, entry->tevlist) {
766                 iov[0].iov_base = (void *)snode->s;
767                 iov[0].iov_len = strlen(snode->s);
768                 iov[1].iov_base = (void *)"\n"; iov[1].iov_len = 1;
769                 ret = writev(fd, iov, 2);
770                 if (ret < (int)iov[0].iov_len + 1)
771                         goto rollback;
772         }
773         return 0;
774
775 rollback:
776         /* Rollback to avoid cache file corruption */
777         if (ret > 0)
778                 ret = -1;
779         if (ftruncate(fd, st.st_size) < 0)
780                 ret = -2;
781
782         return ret;
783 }
784
785 int probe_cache__commit(struct probe_cache *pcache)
786 {
787         struct probe_cache_entry *entry;
788         int ret = 0;
789
790         /* TBD: if we do not update existing entries, skip it */
791         ret = lseek(pcache->fd, 0, SEEK_SET);
792         if (ret < 0)
793                 goto out;
794
795         ret = ftruncate(pcache->fd, 0);
796         if (ret < 0)
797                 goto out;
798
799         for_each_probe_cache_entry(entry, pcache) {
800                 ret = probe_cache_entry__write(entry, pcache->fd);
801                 pr_debug("Cache committed: %d\n", ret);
802                 if (ret < 0)
803                         break;
804         }
805 out:
806         return ret;
807 }
808
809 static bool probe_cache_entry__compare(struct probe_cache_entry *entry,
810                                        struct strfilter *filter)
811 {
812         char buf[128], *ptr = entry->spev;
813
814         if (entry->pev.event) {
815                 snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event);
816                 ptr = buf;
817         }
818         return strfilter__compare(filter, ptr);
819 }
820
821 int probe_cache__filter_purge(struct probe_cache *pcache,
822                               struct strfilter *filter)
823 {
824         struct probe_cache_entry *entry, *tmp;
825
826         list_for_each_entry_safe(entry, tmp, &pcache->entries, node) {
827                 if (probe_cache_entry__compare(entry, filter)) {
828                         pr_info("Removed cached event: %s\n", entry->spev);
829                         list_del_init(&entry->node);
830                         probe_cache_entry__delete(entry);
831                 }
832         }
833         return 0;
834 }
835
836 static int probe_cache__show_entries(struct probe_cache *pcache,
837                                      struct strfilter *filter)
838 {
839         struct probe_cache_entry *entry;
840
841         for_each_probe_cache_entry(entry, pcache) {
842                 if (probe_cache_entry__compare(entry, filter))
843                         printf("%s\n", entry->spev);
844         }
845         return 0;
846 }
847
848 /* Show all cached probes */
849 int probe_cache__show_all_caches(struct strfilter *filter)
850 {
851         struct probe_cache *pcache;
852         struct strlist *bidlist;
853         struct str_node *nd;
854         char *buf = strfilter__string(filter);
855
856         pr_debug("list cache with filter: %s\n", buf);
857         free(buf);
858
859         bidlist = build_id_cache__list_all(true);
860         if (!bidlist) {
861                 pr_debug("Failed to get buildids: %d\n", errno);
862                 return -EINVAL;
863         }
864         strlist__for_each_entry(nd, bidlist) {
865                 pcache = probe_cache__new(nd->s);
866                 if (!pcache)
867                         continue;
868                 if (!list_empty(&pcache->entries)) {
869                         buf = build_id_cache__origname(nd->s);
870                         printf("%s (%s):\n", buf, nd->s);
871                         free(buf);
872                         probe_cache__show_entries(pcache, filter);
873                 }
874                 probe_cache__delete(pcache);
875         }
876         strlist__delete(bidlist);
877
878         return 0;
879 }