1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * probe-file.c : operate ftrace k/uprobe events files 4 * 5 * Written by Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> 6 */ 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <sys/stat.h> 10 #include <sys/types.h> 11 #include <sys/uio.h> 12 #include <unistd.h> 13 #include <linux/zalloc.h> 14 #include "namespaces.h" 15 #include "event.h" 16 #include "strlist.h" 17 #include "strfilter.h" 18 #include "debug.h" 19 #include "build-id.h" 20 #include "dso.h" 21 #include "color.h" 22 #include "symbol.h" 23 #include "strbuf.h" 24 #include <api/fs/tracing_path.h> 25 #include "probe-event.h" 26 #include "probe-file.h" 27 #include "session.h" 28 #include "perf_regs.h" 29 #include "string2.h" 30 31 /* 4096 - 2 ('\n' + '\0') */ 32 #define MAX_CMDLEN 4094 33 34 static void print_open_warning(int err, bool uprobe) 35 { 36 char sbuf[STRERR_BUFSIZE]; 37 38 if (err == -ENOENT) { 39 const char *config; 40 41 if (uprobe) 42 config = "CONFIG_UPROBE_EVENTS"; 43 else 44 config = "CONFIG_KPROBE_EVENTS"; 45 46 pr_warning("%cprobe_events file does not exist" 47 " - please rebuild kernel with %s.\n", 48 uprobe ? 'u' : 'k', config); 49 } else if (err == -ENOTSUP) 50 pr_warning("Tracefs or debugfs is not mounted.\n"); 51 else 52 pr_warning("Failed to open %cprobe_events: %s\n", 53 uprobe ? 'u' : 'k', 54 str_error_r(-err, sbuf, sizeof(sbuf))); 55 } 56 57 static void print_both_open_warning(int kerr, int uerr) 58 { 59 /* Both kprobes and uprobes are disabled, warn it. */ 60 if (kerr == -ENOTSUP && uerr == -ENOTSUP) 61 pr_warning("Tracefs or debugfs is not mounted.\n"); 62 else if (kerr == -ENOENT && uerr == -ENOENT) 63 pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS " 64 "or/and CONFIG_UPROBE_EVENTS.\n"); 65 else { 66 char sbuf[STRERR_BUFSIZE]; 67 pr_warning("Failed to open kprobe events: %s.\n", 68 str_error_r(-kerr, sbuf, sizeof(sbuf))); 69 pr_warning("Failed to open uprobe events: %s.\n", 70 str_error_r(-uerr, sbuf, sizeof(sbuf))); 71 } 72 } 73 74 int open_trace_file(const char *trace_file, bool readwrite) 75 { 76 char buf[PATH_MAX]; 77 int ret; 78 79 ret = e_snprintf(buf, PATH_MAX, "%s/%s", tracing_path_mount(), trace_file); 80 if (ret >= 0) { 81 pr_debug("Opening %s write=%d\n", buf, readwrite); 82 if (readwrite && !probe_event_dry_run) 83 ret = open(buf, O_RDWR | O_APPEND, 0); 84 else 85 ret = open(buf, O_RDONLY, 0); 86 87 if (ret < 0) 88 ret = -errno; 89 } 90 return ret; 91 } 92 93 static int open_kprobe_events(bool readwrite) 94 { 95 return open_trace_file("kprobe_events", readwrite); 96 } 97 98 static int open_uprobe_events(bool readwrite) 99 { 100 return open_trace_file("uprobe_events", readwrite); 101 } 102 103 int probe_file__open(int flag) 104 { 105 int fd; 106 107 if (flag & PF_FL_UPROBE) 108 fd = open_uprobe_events(flag & PF_FL_RW); 109 else 110 fd = open_kprobe_events(flag & PF_FL_RW); 111 if (fd < 0) 112 print_open_warning(fd, flag & PF_FL_UPROBE); 113 114 return fd; 115 } 116 117 int probe_file__open_both(int *kfd, int *ufd, int flag) 118 { 119 if (!kfd || !ufd) 120 return -EINVAL; 121 122 *kfd = open_kprobe_events(flag & PF_FL_RW); 123 *ufd = open_uprobe_events(flag & PF_FL_RW); 124 if (*kfd < 0 && *ufd < 0) { 125 print_both_open_warning(*kfd, *ufd); 126 return *kfd; 127 } 128 129 return 0; 130 } 131 132 /* Get raw string list of current kprobe_events or uprobe_events */ 133 struct strlist *probe_file__get_rawlist(int fd) 134 { 135 int ret, idx, fddup; 136 FILE *fp; 137 char buf[MAX_CMDLEN]; 138 char *p; 139 struct strlist *sl; 140 141 if (fd < 0) 142 return NULL; 143 144 sl = strlist__new(NULL, NULL); 145 if (sl == NULL) 146 return NULL; 147 148 fddup = dup(fd); 149 if (fddup < 0) 150 goto out_free_sl; 151 152 fp = fdopen(fddup, "r"); 153 if (!fp) 154 goto out_close_fddup; 155 156 while (!feof(fp)) { 157 p = fgets(buf, MAX_CMDLEN, fp); 158 if (!p) 159 break; 160 161 idx = strlen(p) - 1; 162 if (p[idx] == '\n') 163 p[idx] = '\0'; 164 ret = strlist__add(sl, buf); 165 if (ret < 0) { 166 pr_debug("strlist__add failed (%d)\n", ret); 167 goto out_close_fp; 168 } 169 } 170 fclose(fp); 171 172 return sl; 173 174 out_close_fp: 175 fclose(fp); 176 goto out_free_sl; 177 out_close_fddup: 178 close(fddup); 179 out_free_sl: 180 strlist__delete(sl); 181 return NULL; 182 } 183 184 static struct strlist *__probe_file__get_namelist(int fd, bool include_group) 185 { 186 char buf[128]; 187 struct strlist *sl, *rawlist; 188 struct str_node *ent; 189 struct probe_trace_event tev; 190 int ret = 0; 191 192 memset(&tev, 0, sizeof(tev)); 193 rawlist = probe_file__get_rawlist(fd); 194 if (!rawlist) 195 return NULL; 196 sl = strlist__new(NULL, NULL); 197 strlist__for_each_entry(ent, rawlist) { 198 ret = parse_probe_trace_command(ent->s, &tev); 199 if (ret < 0) 200 break; 201 if (include_group) { 202 ret = e_snprintf(buf, 128, "%s:%s", tev.group, 203 tev.event); 204 if (ret >= 0) 205 ret = strlist__add(sl, buf); 206 } else 207 ret = strlist__add(sl, tev.event); 208 clear_probe_trace_event(&tev); 209 /* Skip if there is same name multi-probe event in the list */ 210 if (ret == -EEXIST) 211 ret = 0; 212 if (ret < 0) 213 break; 214 } 215 strlist__delete(rawlist); 216 217 if (ret < 0) { 218 strlist__delete(sl); 219 return NULL; 220 } 221 return sl; 222 } 223 224 /* Get current perf-probe event names */ 225 struct strlist *probe_file__get_namelist(int fd) 226 { 227 return __probe_file__get_namelist(fd, false); 228 } 229 230 int probe_file__add_event(int fd, struct probe_trace_event *tev) 231 { 232 int ret = 0; 233 char *buf = synthesize_probe_trace_command(tev); 234 char sbuf[STRERR_BUFSIZE]; 235 236 if (!buf) { 237 pr_debug("Failed to synthesize probe trace event.\n"); 238 return -EINVAL; 239 } 240 241 pr_debug("Writing event: %s\n", buf); 242 if (!probe_event_dry_run) { 243 if (write(fd, buf, strlen(buf)) < (int)strlen(buf)) { 244 ret = -errno; 245 pr_warning("Failed to write event: %s\n", 246 str_error_r(errno, sbuf, sizeof(sbuf))); 247 } 248 } 249 free(buf); 250 251 return ret; 252 } 253 254 static int __del_trace_probe_event(int fd, struct str_node *ent) 255 { 256 char *p; 257 char buf[128]; 258 int ret; 259 260 /* Convert from perf-probe event to trace-probe event */ 261 ret = e_snprintf(buf, 128, "-:%s", ent->s); 262 if (ret < 0) 263 goto error; 264 265 p = strchr(buf + 2, ':'); 266 if (!p) { 267 pr_debug("Internal error: %s should have ':' but not.\n", 268 ent->s); 269 ret = -ENOTSUP; 270 goto error; 271 } 272 *p = '/'; 273 274 pr_debug("Writing event: %s\n", buf); 275 ret = write(fd, buf, strlen(buf)); 276 if (ret < 0) { 277 ret = -errno; 278 goto error; 279 } 280 281 return 0; 282 error: 283 pr_warning("Failed to delete event: %s\n", 284 str_error_r(-ret, buf, sizeof(buf))); 285 return ret; 286 } 287 288 int probe_file__get_events(int fd, struct strfilter *filter, 289 struct strlist *plist) 290 { 291 struct strlist *namelist; 292 struct str_node *ent; 293 const char *p; 294 int ret = -ENOENT; 295 296 if (!plist) 297 return -EINVAL; 298 299 namelist = __probe_file__get_namelist(fd, true); 300 if (!namelist) 301 return -ENOENT; 302 303 strlist__for_each_entry(ent, namelist) { 304 p = strchr(ent->s, ':'); 305 if ((p && strfilter__compare(filter, p + 1)) || 306 strfilter__compare(filter, ent->s)) { 307 ret = strlist__add(plist, ent->s); 308 if (ret == -ENOMEM) { 309 pr_err("strlist__add failed with -ENOMEM\n"); 310 goto out; 311 } 312 ret = 0; 313 } 314 } 315 out: 316 strlist__delete(namelist); 317 318 return ret; 319 } 320 321 int probe_file__del_strlist(int fd, struct strlist *namelist) 322 { 323 int ret = 0; 324 struct str_node *ent; 325 326 strlist__for_each_entry(ent, namelist) { 327 ret = __del_trace_probe_event(fd, ent); 328 if (ret < 0) 329 break; 330 } 331 return ret; 332 } 333 334 int probe_file__del_events(int fd, struct strfilter *filter) 335 { 336 struct strlist *namelist; 337 int ret; 338 339 namelist = strlist__new(NULL, NULL); 340 if (!namelist) 341 return -ENOMEM; 342 343 ret = probe_file__get_events(fd, filter, namelist); 344 if (ret < 0) 345 return ret; 346 347 ret = probe_file__del_strlist(fd, namelist); 348 strlist__delete(namelist); 349 350 return ret; 351 } 352 353 /* Caller must ensure to remove this entry from list */ 354 static void probe_cache_entry__delete(struct probe_cache_entry *entry) 355 { 356 if (entry) { 357 BUG_ON(!list_empty(&entry->node)); 358 359 strlist__delete(entry->tevlist); 360 clear_perf_probe_event(&entry->pev); 361 zfree(&entry->spev); 362 free(entry); 363 } 364 } 365 366 static struct probe_cache_entry * 367 probe_cache_entry__new(struct perf_probe_event *pev) 368 { 369 struct probe_cache_entry *entry = zalloc(sizeof(*entry)); 370 371 if (entry) { 372 INIT_LIST_HEAD(&entry->node); 373 entry->tevlist = strlist__new(NULL, NULL); 374 if (!entry->tevlist) 375 zfree(&entry); 376 else if (pev) { 377 entry->spev = synthesize_perf_probe_command(pev); 378 if (!entry->spev || 379 perf_probe_event__copy(&entry->pev, pev) < 0) { 380 probe_cache_entry__delete(entry); 381 return NULL; 382 } 383 } 384 } 385 386 return entry; 387 } 388 389 int probe_cache_entry__get_event(struct probe_cache_entry *entry, 390 struct probe_trace_event **tevs) 391 { 392 struct probe_trace_event *tev; 393 struct str_node *node; 394 int ret, i; 395 396 ret = strlist__nr_entries(entry->tevlist); 397 if (ret > probe_conf.max_probes) 398 return -E2BIG; 399 400 *tevs = zalloc(ret * sizeof(*tev)); 401 if (!*tevs) 402 return -ENOMEM; 403 404 i = 0; 405 strlist__for_each_entry(node, entry->tevlist) { 406 tev = &(*tevs)[i++]; 407 ret = parse_probe_trace_command(node->s, tev); 408 if (ret < 0) 409 break; 410 } 411 return i; 412 } 413 414 /* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */ 415 static int probe_cache__open(struct probe_cache *pcache, const char *target, 416 struct nsinfo *nsi) 417 { 418 char cpath[PATH_MAX]; 419 char sbuildid[SBUILD_ID_SIZE]; 420 char *dir_name = NULL; 421 bool is_kallsyms = false; 422 int ret, fd; 423 struct nscookie nsc; 424 425 if (target && build_id_cache__cached(target)) { 426 /* This is a cached buildid */ 427 strlcpy(sbuildid, target, SBUILD_ID_SIZE); 428 dir_name = build_id_cache__linkname(sbuildid, NULL, 0); 429 goto found; 430 } 431 432 if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) { 433 target = DSO__NAME_KALLSYMS; 434 is_kallsyms = true; 435 ret = sysfs__sprintf_build_id("/", sbuildid); 436 } else { 437 nsinfo__mountns_enter(nsi, &nsc); 438 ret = filename__sprintf_build_id(target, sbuildid); 439 nsinfo__mountns_exit(&nsc); 440 } 441 442 if (ret < 0) { 443 pr_debug("Failed to get build-id from %s.\n", target); 444 return ret; 445 } 446 447 /* If we have no buildid cache, make it */ 448 if (!build_id_cache__cached(sbuildid)) { 449 ret = build_id_cache__add_s(sbuildid, target, nsi, 450 is_kallsyms, NULL); 451 if (ret < 0) { 452 pr_debug("Failed to add build-id cache: %s\n", target); 453 return ret; 454 } 455 } 456 457 dir_name = build_id_cache__cachedir(sbuildid, target, nsi, is_kallsyms, 458 false); 459 found: 460 if (!dir_name) { 461 pr_debug("Failed to get cache from %s\n", target); 462 return -ENOMEM; 463 } 464 465 snprintf(cpath, PATH_MAX, "%s/probes", dir_name); 466 fd = open(cpath, O_CREAT | O_RDWR, 0644); 467 if (fd < 0) 468 pr_debug("Failed to open cache(%d): %s\n", fd, cpath); 469 free(dir_name); 470 pcache->fd = fd; 471 472 return fd; 473 } 474 475 static int probe_cache__load(struct probe_cache *pcache) 476 { 477 struct probe_cache_entry *entry = NULL; 478 char buf[MAX_CMDLEN], *p; 479 int ret = 0, fddup; 480 FILE *fp; 481 482 fddup = dup(pcache->fd); 483 if (fddup < 0) 484 return -errno; 485 fp = fdopen(fddup, "r"); 486 if (!fp) { 487 close(fddup); 488 return -EINVAL; 489 } 490 491 while (!feof(fp)) { 492 if (!fgets(buf, MAX_CMDLEN, fp)) 493 break; 494 p = strchr(buf, '\n'); 495 if (p) 496 *p = '\0'; 497 /* #perf_probe_event or %sdt_event */ 498 if (buf[0] == '#' || buf[0] == '%') { 499 entry = probe_cache_entry__new(NULL); 500 if (!entry) { 501 ret = -ENOMEM; 502 goto out; 503 } 504 if (buf[0] == '%') 505 entry->sdt = true; 506 entry->spev = strdup(buf + 1); 507 if (entry->spev) 508 ret = parse_perf_probe_command(buf + 1, 509 &entry->pev); 510 else 511 ret = -ENOMEM; 512 if (ret < 0) { 513 probe_cache_entry__delete(entry); 514 goto out; 515 } 516 list_add_tail(&entry->node, &pcache->entries); 517 } else { /* trace_probe_event */ 518 if (!entry) { 519 ret = -EINVAL; 520 goto out; 521 } 522 ret = strlist__add(entry->tevlist, buf); 523 if (ret == -ENOMEM) { 524 pr_err("strlist__add failed with -ENOMEM\n"); 525 goto out; 526 } 527 } 528 } 529 out: 530 fclose(fp); 531 return ret; 532 } 533 534 static struct probe_cache *probe_cache__alloc(void) 535 { 536 struct probe_cache *pcache = zalloc(sizeof(*pcache)); 537 538 if (pcache) { 539 INIT_LIST_HEAD(&pcache->entries); 540 pcache->fd = -EINVAL; 541 } 542 return pcache; 543 } 544 545 void probe_cache__purge(struct probe_cache *pcache) 546 { 547 struct probe_cache_entry *entry, *n; 548 549 list_for_each_entry_safe(entry, n, &pcache->entries, node) { 550 list_del_init(&entry->node); 551 probe_cache_entry__delete(entry); 552 } 553 } 554 555 void probe_cache__delete(struct probe_cache *pcache) 556 { 557 if (!pcache) 558 return; 559 560 probe_cache__purge(pcache); 561 if (pcache->fd > 0) 562 close(pcache->fd); 563 free(pcache); 564 } 565 566 struct probe_cache *probe_cache__new(const char *target, struct nsinfo *nsi) 567 { 568 struct probe_cache *pcache = probe_cache__alloc(); 569 int ret; 570 571 if (!pcache) 572 return NULL; 573 574 ret = probe_cache__open(pcache, target, nsi); 575 if (ret < 0) { 576 pr_debug("Cache open error: %d\n", ret); 577 goto out_err; 578 } 579 580 ret = probe_cache__load(pcache); 581 if (ret < 0) { 582 pr_debug("Cache read error: %d\n", ret); 583 goto out_err; 584 } 585 586 return pcache; 587 588 out_err: 589 probe_cache__delete(pcache); 590 return NULL; 591 } 592 593 static bool streql(const char *a, const char *b) 594 { 595 if (a == b) 596 return true; 597 598 if (!a || !b) 599 return false; 600 601 return !strcmp(a, b); 602 } 603 604 struct probe_cache_entry * 605 probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev) 606 { 607 struct probe_cache_entry *entry = NULL; 608 char *cmd = synthesize_perf_probe_command(pev); 609 610 if (!cmd) 611 return NULL; 612 613 for_each_probe_cache_entry(entry, pcache) { 614 if (pev->sdt) { 615 if (entry->pev.event && 616 streql(entry->pev.event, pev->event) && 617 (!pev->group || 618 streql(entry->pev.group, pev->group))) 619 goto found; 620 621 continue; 622 } 623 /* Hit if same event name or same command-string */ 624 if ((pev->event && 625 (streql(entry->pev.group, pev->group) && 626 streql(entry->pev.event, pev->event))) || 627 (!strcmp(entry->spev, cmd))) 628 goto found; 629 } 630 entry = NULL; 631 632 found: 633 free(cmd); 634 return entry; 635 } 636 637 struct probe_cache_entry * 638 probe_cache__find_by_name(struct probe_cache *pcache, 639 const char *group, const char *event) 640 { 641 struct probe_cache_entry *entry = NULL; 642 643 for_each_probe_cache_entry(entry, pcache) { 644 /* Hit if same event name or same command-string */ 645 if (streql(entry->pev.group, group) && 646 streql(entry->pev.event, event)) 647 goto found; 648 } 649 entry = NULL; 650 651 found: 652 return entry; 653 } 654 655 int probe_cache__add_entry(struct probe_cache *pcache, 656 struct perf_probe_event *pev, 657 struct probe_trace_event *tevs, int ntevs) 658 { 659 struct probe_cache_entry *entry = NULL; 660 char *command; 661 int i, ret = 0; 662 663 if (!pcache || !pev || !tevs || ntevs <= 0) { 664 ret = -EINVAL; 665 goto out_err; 666 } 667 668 /* Remove old cache entry */ 669 entry = probe_cache__find(pcache, pev); 670 if (entry) { 671 list_del_init(&entry->node); 672 probe_cache_entry__delete(entry); 673 } 674 675 ret = -ENOMEM; 676 entry = probe_cache_entry__new(pev); 677 if (!entry) 678 goto out_err; 679 680 for (i = 0; i < ntevs; i++) { 681 if (!tevs[i].point.symbol) 682 continue; 683 684 command = synthesize_probe_trace_command(&tevs[i]); 685 if (!command) 686 goto out_err; 687 ret = strlist__add(entry->tevlist, command); 688 if (ret == -ENOMEM) { 689 pr_err("strlist__add failed with -ENOMEM\n"); 690 goto out_err; 691 } 692 693 free(command); 694 } 695 list_add_tail(&entry->node, &pcache->entries); 696 pr_debug("Added probe cache: %d\n", ntevs); 697 return 0; 698 699 out_err: 700 pr_debug("Failed to add probe caches\n"); 701 probe_cache_entry__delete(entry); 702 return ret; 703 } 704 705 #ifdef HAVE_GELF_GETNOTE_SUPPORT 706 static unsigned long long sdt_note__get_addr(struct sdt_note *note) 707 { 708 return note->bit32 ? 709 (unsigned long long)note->addr.a32[SDT_NOTE_IDX_LOC] : 710 (unsigned long long)note->addr.a64[SDT_NOTE_IDX_LOC]; 711 } 712 713 static unsigned long long sdt_note__get_ref_ctr_offset(struct sdt_note *note) 714 { 715 return note->bit32 ? 716 (unsigned long long)note->addr.a32[SDT_NOTE_IDX_REFCTR] : 717 (unsigned long long)note->addr.a64[SDT_NOTE_IDX_REFCTR]; 718 } 719 720 static const char * const type_to_suffix[] = { 721 ":s64", "", "", "", ":s32", "", ":s16", ":s8", 722 "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" 723 }; 724 725 /* 726 * Isolate the string number and convert it into a decimal value; 727 * this will be an index to get suffix of the uprobe name (defining 728 * the type) 729 */ 730 static int sdt_arg_parse_size(char *n_ptr, const char **suffix) 731 { 732 long type_idx; 733 734 type_idx = strtol(n_ptr, NULL, 10); 735 if (type_idx < -8 || type_idx > 8) { 736 pr_debug4("Failed to get a valid sdt type\n"); 737 return -1; 738 } 739 740 *suffix = type_to_suffix[type_idx + 8]; 741 return 0; 742 } 743 744 static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) 745 { 746 char *op, *desc = strdup(arg), *new_op = NULL; 747 const char *suffix = ""; 748 int ret = -1; 749 750 if (desc == NULL) { 751 pr_debug4("Allocation error\n"); 752 return ret; 753 } 754 755 /* 756 * Argument is in N@OP format. N is size of the argument and OP is 757 * the actual assembly operand. N can be omitted; in that case 758 * argument is just OP(without @). 759 */ 760 op = strchr(desc, '@'); 761 if (op) { 762 op[0] = '\0'; 763 op++; 764 765 if (sdt_arg_parse_size(desc, &suffix)) 766 goto error; 767 } else { 768 op = desc; 769 } 770 771 ret = arch_sdt_arg_parse_op(op, &new_op); 772 773 if (ret < 0) 774 goto error; 775 776 if (ret == SDT_ARG_VALID) { 777 ret = strbuf_addf(buf, " arg%d=%s%s", i + 1, new_op, suffix); 778 if (ret < 0) 779 goto error; 780 } 781 782 ret = 0; 783 error: 784 free(desc); 785 free(new_op); 786 return ret; 787 } 788 789 static char *synthesize_sdt_probe_command(struct sdt_note *note, 790 const char *pathname, 791 const char *sdtgrp) 792 { 793 struct strbuf buf; 794 char *ret = NULL, **args; 795 int i, args_count, err; 796 unsigned long long ref_ctr_offset; 797 798 if (strbuf_init(&buf, 32) < 0) 799 return NULL; 800 801 err = strbuf_addf(&buf, "p:%s/%s %s:0x%llx", 802 sdtgrp, note->name, pathname, 803 sdt_note__get_addr(note)); 804 805 ref_ctr_offset = sdt_note__get_ref_ctr_offset(note); 806 if (ref_ctr_offset && err >= 0) 807 err = strbuf_addf(&buf, "(0x%llx)", ref_ctr_offset); 808 809 if (err < 0) 810 goto error; 811 812 if (!note->args) 813 goto out; 814 815 if (note->args) { 816 args = argv_split(note->args, &args_count); 817 818 for (i = 0; i < args_count; ++i) { 819 if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) 820 goto error; 821 } 822 } 823 824 out: 825 ret = strbuf_detach(&buf, NULL); 826 error: 827 strbuf_release(&buf); 828 return ret; 829 } 830 831 int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) 832 { 833 struct probe_cache_entry *entry = NULL; 834 struct list_head sdtlist; 835 struct sdt_note *note; 836 char *buf; 837 char sdtgrp[64]; 838 int ret; 839 840 INIT_LIST_HEAD(&sdtlist); 841 ret = get_sdt_note_list(&sdtlist, pathname); 842 if (ret < 0) { 843 pr_debug4("Failed to get sdt note: %d\n", ret); 844 return ret; 845 } 846 list_for_each_entry(note, &sdtlist, note_list) { 847 ret = snprintf(sdtgrp, 64, "sdt_%s", note->provider); 848 if (ret < 0) 849 break; 850 /* Try to find same-name entry */ 851 entry = probe_cache__find_by_name(pcache, sdtgrp, note->name); 852 if (!entry) { 853 entry = probe_cache_entry__new(NULL); 854 if (!entry) { 855 ret = -ENOMEM; 856 break; 857 } 858 entry->sdt = true; 859 ret = asprintf(&entry->spev, "%s:%s=%s", sdtgrp, 860 note->name, note->name); 861 if (ret < 0) 862 break; 863 entry->pev.event = strdup(note->name); 864 entry->pev.group = strdup(sdtgrp); 865 list_add_tail(&entry->node, &pcache->entries); 866 } 867 buf = synthesize_sdt_probe_command(note, pathname, sdtgrp); 868 if (!buf) { 869 ret = -ENOMEM; 870 break; 871 } 872 873 ret = strlist__add(entry->tevlist, buf); 874 875 free(buf); 876 entry = NULL; 877 878 if (ret == -ENOMEM) { 879 pr_err("strlist__add failed with -ENOMEM\n"); 880 break; 881 } 882 } 883 if (entry) { 884 list_del_init(&entry->node); 885 probe_cache_entry__delete(entry); 886 } 887 cleanup_sdt_note_list(&sdtlist); 888 return ret; 889 } 890 #endif 891 892 static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd) 893 { 894 struct str_node *snode; 895 struct stat st; 896 struct iovec iov[3]; 897 const char *prefix = entry->sdt ? "%" : "#"; 898 int ret; 899 /* Save stat for rollback */ 900 ret = fstat(fd, &st); 901 if (ret < 0) 902 return ret; 903 904 pr_debug("Writing cache: %s%s\n", prefix, entry->spev); 905 iov[0].iov_base = (void *)prefix; iov[0].iov_len = 1; 906 iov[1].iov_base = entry->spev; iov[1].iov_len = strlen(entry->spev); 907 iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1; 908 ret = writev(fd, iov, 3); 909 if (ret < (int)iov[1].iov_len + 2) 910 goto rollback; 911 912 strlist__for_each_entry(snode, entry->tevlist) { 913 iov[0].iov_base = (void *)snode->s; 914 iov[0].iov_len = strlen(snode->s); 915 iov[1].iov_base = (void *)"\n"; iov[1].iov_len = 1; 916 ret = writev(fd, iov, 2); 917 if (ret < (int)iov[0].iov_len + 1) 918 goto rollback; 919 } 920 return 0; 921 922 rollback: 923 /* Rollback to avoid cache file corruption */ 924 if (ret > 0) 925 ret = -1; 926 if (ftruncate(fd, st.st_size) < 0) 927 ret = -2; 928 929 return ret; 930 } 931 932 int probe_cache__commit(struct probe_cache *pcache) 933 { 934 struct probe_cache_entry *entry; 935 int ret = 0; 936 937 /* TBD: if we do not update existing entries, skip it */ 938 ret = lseek(pcache->fd, 0, SEEK_SET); 939 if (ret < 0) 940 goto out; 941 942 ret = ftruncate(pcache->fd, 0); 943 if (ret < 0) 944 goto out; 945 946 for_each_probe_cache_entry(entry, pcache) { 947 ret = probe_cache_entry__write(entry, pcache->fd); 948 pr_debug("Cache committed: %d\n", ret); 949 if (ret < 0) 950 break; 951 } 952 out: 953 return ret; 954 } 955 956 static bool probe_cache_entry__compare(struct probe_cache_entry *entry, 957 struct strfilter *filter) 958 { 959 char buf[128], *ptr = entry->spev; 960 961 if (entry->pev.event) { 962 snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event); 963 ptr = buf; 964 } 965 return strfilter__compare(filter, ptr); 966 } 967 968 int probe_cache__filter_purge(struct probe_cache *pcache, 969 struct strfilter *filter) 970 { 971 struct probe_cache_entry *entry, *tmp; 972 973 list_for_each_entry_safe(entry, tmp, &pcache->entries, node) { 974 if (probe_cache_entry__compare(entry, filter)) { 975 pr_info("Removed cached event: %s\n", entry->spev); 976 list_del_init(&entry->node); 977 probe_cache_entry__delete(entry); 978 } 979 } 980 return 0; 981 } 982 983 static int probe_cache__show_entries(struct probe_cache *pcache, 984 struct strfilter *filter) 985 { 986 struct probe_cache_entry *entry; 987 988 for_each_probe_cache_entry(entry, pcache) { 989 if (probe_cache_entry__compare(entry, filter)) 990 printf("%s\n", entry->spev); 991 } 992 return 0; 993 } 994 995 /* Show all cached probes */ 996 int probe_cache__show_all_caches(struct strfilter *filter) 997 { 998 struct probe_cache *pcache; 999 struct strlist *bidlist; 1000 struct str_node *nd; 1001 char *buf = strfilter__string(filter); 1002 1003 pr_debug("list cache with filter: %s\n", buf); 1004 free(buf); 1005 1006 bidlist = build_id_cache__list_all(true); 1007 if (!bidlist) { 1008 pr_debug("Failed to get buildids: %d\n", errno); 1009 return -EINVAL; 1010 } 1011 strlist__for_each_entry(nd, bidlist) { 1012 pcache = probe_cache__new(nd->s, NULL); 1013 if (!pcache) 1014 continue; 1015 if (!list_empty(&pcache->entries)) { 1016 buf = build_id_cache__origname(nd->s); 1017 printf("%s (%s):\n", buf, nd->s); 1018 free(buf); 1019 probe_cache__show_entries(pcache, filter); 1020 } 1021 probe_cache__delete(pcache); 1022 } 1023 strlist__delete(bidlist); 1024 1025 return 0; 1026 } 1027 1028 enum ftrace_readme { 1029 FTRACE_README_PROBE_TYPE_X = 0, 1030 FTRACE_README_KRETPROBE_OFFSET, 1031 FTRACE_README_UPROBE_REF_CTR, 1032 FTRACE_README_USER_ACCESS, 1033 FTRACE_README_MULTIPROBE_EVENT, 1034 FTRACE_README_IMMEDIATE_VALUE, 1035 FTRACE_README_END, 1036 }; 1037 1038 static struct { 1039 const char *pattern; 1040 bool avail; 1041 } ftrace_readme_table[] = { 1042 #define DEFINE_TYPE(idx, pat) \ 1043 [idx] = {.pattern = pat, .avail = false} 1044 DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"), 1045 DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"), 1046 DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"), 1047 DEFINE_TYPE(FTRACE_README_USER_ACCESS, "*u]<offset>*"), 1048 DEFINE_TYPE(FTRACE_README_MULTIPROBE_EVENT, "*Create/append/*"), 1049 DEFINE_TYPE(FTRACE_README_IMMEDIATE_VALUE, "*\\imm-value,*"), 1050 }; 1051 1052 static bool scan_ftrace_readme(enum ftrace_readme type) 1053 { 1054 int fd; 1055 FILE *fp; 1056 char *buf = NULL; 1057 size_t len = 0; 1058 bool ret = false; 1059 static bool scanned = false; 1060 1061 if (scanned) 1062 goto result; 1063 1064 fd = open_trace_file("README", false); 1065 if (fd < 0) 1066 return ret; 1067 1068 fp = fdopen(fd, "r"); 1069 if (!fp) { 1070 close(fd); 1071 return ret; 1072 } 1073 1074 while (getline(&buf, &len, fp) > 0) 1075 for (enum ftrace_readme i = 0; i < FTRACE_README_END; i++) 1076 if (!ftrace_readme_table[i].avail) 1077 ftrace_readme_table[i].avail = 1078 strglobmatch(buf, ftrace_readme_table[i].pattern); 1079 scanned = true; 1080 1081 fclose(fp); 1082 free(buf); 1083 1084 result: 1085 if (type >= FTRACE_README_END) 1086 return false; 1087 1088 return ftrace_readme_table[type].avail; 1089 } 1090 1091 bool probe_type_is_available(enum probe_type type) 1092 { 1093 if (type >= PROBE_TYPE_END) 1094 return false; 1095 else if (type == PROBE_TYPE_X) 1096 return scan_ftrace_readme(FTRACE_README_PROBE_TYPE_X); 1097 1098 return true; 1099 } 1100 1101 bool kretprobe_offset_is_supported(void) 1102 { 1103 return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET); 1104 } 1105 1106 bool uprobe_ref_ctr_is_supported(void) 1107 { 1108 return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR); 1109 } 1110 1111 bool user_access_is_supported(void) 1112 { 1113 return scan_ftrace_readme(FTRACE_README_USER_ACCESS); 1114 } 1115 1116 bool multiprobe_event_is_supported(void) 1117 { 1118 return scan_ftrace_readme(FTRACE_README_MULTIPROBE_EVENT); 1119 } 1120 1121 bool immediate_value_is_supported(void) 1122 { 1123 return scan_ftrace_readme(FTRACE_README_IMMEDIATE_VALUE); 1124 } 1125