xref: /openbmc/linux/tools/perf/util/probe-file.c (revision 1491eaf9)
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 }
880