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