linux/tools/perf/util/probe-file.c
<<
>>
Prefs
   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 <errno.h>
  18#include <fcntl.h>
  19#include <sys/stat.h>
  20#include <sys/types.h>
  21#include <sys/uio.h>
  22#include <unistd.h>
  23#include "util.h"
  24#include "event.h"
  25#include "strlist.h"
  26#include "strfilter.h"
  27#include "debug.h"
  28#include "cache.h"
  29#include "color.h"
  30#include "symbol.h"
  31#include "thread.h"
  32#include <api/fs/tracing_path.h>
  33#include "probe-event.h"
  34#include "probe-file.h"
  35#include "session.h"
  36#include "perf_regs.h"
  37#include "string2.h"
  38
  39/* 4096 - 2 ('\n' + '\0') */
  40#define MAX_CMDLEN 4094
  41
  42static void print_open_warning(int err, bool uprobe)
  43{
  44        char sbuf[STRERR_BUFSIZE];
  45
  46        if (err == -ENOENT) {
  47                const char *config;
  48
  49                if (uprobe)
  50                        config = "CONFIG_UPROBE_EVENTS";
  51                else
  52                        config = "CONFIG_KPROBE_EVENTS";
  53
  54                pr_warning("%cprobe_events file does not exist"
  55                           " - please rebuild kernel with %s.\n",
  56                           uprobe ? 'u' : 'k', config);
  57        } else if (err == -ENOTSUP)
  58                pr_warning("Tracefs or debugfs is not mounted.\n");
  59        else
  60                pr_warning("Failed to open %cprobe_events: %s\n",
  61                           uprobe ? 'u' : 'k',
  62                           str_error_r(-err, sbuf, sizeof(sbuf)));
  63}
  64
  65static void print_both_open_warning(int kerr, int uerr)
  66{
  67        /* Both kprobes and uprobes are disabled, warn it. */
  68        if (kerr == -ENOTSUP && uerr == -ENOTSUP)
  69                pr_warning("Tracefs or debugfs is not mounted.\n");
  70        else if (kerr == -ENOENT && uerr == -ENOENT)
  71                pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS "
  72                           "or/and CONFIG_UPROBE_EVENTS.\n");
  73        else {
  74                char sbuf[STRERR_BUFSIZE];
  75                pr_warning("Failed to open kprobe events: %s.\n",
  76                           str_error_r(-kerr, sbuf, sizeof(sbuf)));
  77                pr_warning("Failed to open uprobe events: %s.\n",
  78                           str_error_r(-uerr, sbuf, sizeof(sbuf)));
  79        }
  80}
  81
  82int open_trace_file(const char *trace_file, bool readwrite)
  83{
  84        char buf[PATH_MAX];
  85        int ret;
  86
  87        ret = e_snprintf(buf, PATH_MAX, "%s/%s", tracing_path_mount(), trace_file);
  88        if (ret >= 0) {
  89                pr_debug("Opening %s write=%d\n", buf, readwrite);
  90                if (readwrite && !probe_event_dry_run)
  91                        ret = open(buf, O_RDWR | O_APPEND, 0);
  92                else
  93                        ret = open(buf, O_RDONLY, 0);
  94
  95                if (ret < 0)
  96                        ret = -errno;
  97        }
  98        return ret;
  99}
 100
 101static int open_kprobe_events(bool readwrite)
 102{
 103        return open_trace_file("kprobe_events", readwrite);
 104}
 105
 106static int open_uprobe_events(bool readwrite)
 107{
 108        return open_trace_file("uprobe_events", readwrite);
 109}
 110
 111int probe_file__open(int flag)
 112{
 113        int fd;
 114
 115        if (flag & PF_FL_UPROBE)
 116                fd = open_uprobe_events(flag & PF_FL_RW);
 117        else
 118                fd = open_kprobe_events(flag & PF_FL_RW);
 119        if (fd < 0)
 120                print_open_warning(fd, flag & PF_FL_UPROBE);
 121
 122        return fd;
 123}
 124
 125int probe_file__open_both(int *kfd, int *ufd, int flag)
 126{
 127        if (!kfd || !ufd)
 128                return -EINVAL;
 129
 130        *kfd = open_kprobe_events(flag & PF_FL_RW);
 131        *ufd = open_uprobe_events(flag & PF_FL_RW);
 132        if (*kfd < 0 && *ufd < 0) {
 133                print_both_open_warning(*kfd, *ufd);
 134                return *kfd;
 135        }
 136
 137        return 0;
 138}
 139
 140/* Get raw string list of current kprobe_events  or uprobe_events */
 141struct strlist *probe_file__get_rawlist(int fd)
 142{
 143        int ret, idx, fddup;
 144        FILE *fp;
 145        char buf[MAX_CMDLEN];
 146        char *p;
 147        struct strlist *sl;
 148
 149        if (fd < 0)
 150                return NULL;
 151
 152        sl = strlist__new(NULL, NULL);
 153        if (sl == NULL)
 154                return NULL;
 155
 156        fddup = dup(fd);
 157        if (fddup < 0)
 158                goto out_free_sl;
 159
 160        fp = fdopen(fddup, "r");
 161        if (!fp)
 162                goto out_close_fddup;
 163
 164        while (!feof(fp)) {
 165                p = fgets(buf, MAX_CMDLEN, fp);
 166                if (!p)
 167                        break;
 168
 169                idx = strlen(p) - 1;
 170                if (p[idx] == '\n')
 171                        p[idx] = '\0';
 172                ret = strlist__add(sl, buf);
 173                if (ret < 0) {
 174                        pr_debug("strlist__add failed (%d)\n", ret);
 175                        goto out_close_fp;
 176                }
 177        }
 178        fclose(fp);
 179
 180        return sl;
 181
 182out_close_fp:
 183        fclose(fp);
 184        goto out_free_sl;
 185out_close_fddup:
 186        close(fddup);
 187out_free_sl:
 188        strlist__delete(sl);
 189        return NULL;
 190}
 191
 192static struct strlist *__probe_file__get_namelist(int fd, bool include_group)
 193{
 194        char buf[128];
 195        struct strlist *sl, *rawlist;
 196        struct str_node *ent;
 197        struct probe_trace_event tev;
 198        int ret = 0;
 199
 200        memset(&tev, 0, sizeof(tev));
 201        rawlist = probe_file__get_rawlist(fd);
 202        if (!rawlist)
 203                return NULL;
 204        sl = strlist__new(NULL, NULL);
 205        strlist__for_each_entry(ent, rawlist) {
 206                ret = parse_probe_trace_command(ent->s, &tev);
 207                if (ret < 0)
 208                        break;
 209                if (include_group) {
 210                        ret = e_snprintf(buf, 128, "%s:%s", tev.group,
 211                                        tev.event);
 212                        if (ret >= 0)
 213                                ret = strlist__add(sl, buf);
 214                } else
 215                        ret = strlist__add(sl, tev.event);
 216                clear_probe_trace_event(&tev);
 217                if (ret < 0)
 218                        break;
 219        }
 220        strlist__delete(rawlist);
 221
 222        if (ret < 0) {
 223                strlist__delete(sl);
 224                return NULL;
 225        }
 226        return sl;
 227}
 228
 229/* Get current perf-probe event names */
 230struct strlist *probe_file__get_namelist(int fd)
 231{
 232        return __probe_file__get_namelist(fd, false);
 233}
 234
 235int probe_file__add_event(int fd, struct probe_trace_event *tev)
 236{
 237        int ret = 0;
 238        char *buf = synthesize_probe_trace_command(tev);
 239        char sbuf[STRERR_BUFSIZE];
 240
 241        if (!buf) {
 242                pr_debug("Failed to synthesize probe trace event.\n");
 243                return -EINVAL;
 244        }
 245
 246        pr_debug("Writing event: %s\n", buf);
 247        if (!probe_event_dry_run) {
 248                if (write(fd, buf, strlen(buf)) < (int)strlen(buf)) {
 249                        ret = -errno;
 250                        pr_warning("Failed to write event: %s\n",
 251                                   str_error_r(errno, sbuf, sizeof(sbuf)));
 252                }
 253        }
 254        free(buf);
 255
 256        return ret;
 257}
 258
 259static int __del_trace_probe_event(int fd, struct str_node *ent)
 260{
 261        char *p;
 262        char buf[128];
 263        int ret;
 264
 265        /* Convert from perf-probe event to trace-probe event */
 266        ret = e_snprintf(buf, 128, "-:%s", ent->s);
 267        if (ret < 0)
 268                goto error;
 269
 270        p = strchr(buf + 2, ':');
 271        if (!p) {
 272                pr_debug("Internal error: %s should have ':' but not.\n",
 273                         ent->s);
 274                ret = -ENOTSUP;
 275                goto error;
 276        }
 277        *p = '/';
 278
 279        pr_debug("Writing event: %s\n", buf);
 280        ret = write(fd, buf, strlen(buf));
 281        if (ret < 0) {
 282                ret = -errno;
 283                goto error;
 284        }
 285
 286        return 0;
 287error:
 288        pr_warning("Failed to delete event: %s\n",
 289                   str_error_r(-ret, buf, sizeof(buf)));
 290        return ret;
 291}
 292
 293int probe_file__get_events(int fd, struct strfilter *filter,
 294                           struct strlist *plist)
 295{
 296        struct strlist *namelist;
 297        struct str_node *ent;
 298        const char *p;
 299        int ret = -ENOENT;
 300
 301        if (!plist)
 302                return -EINVAL;
 303
 304        namelist = __probe_file__get_namelist(fd, true);
 305        if (!namelist)
 306                return -ENOENT;
 307
 308        strlist__for_each_entry(ent, namelist) {
 309                p = strchr(ent->s, ':');
 310                if ((p && strfilter__compare(filter, p + 1)) ||
 311                    strfilter__compare(filter, ent->s)) {
 312                        strlist__add(plist, ent->s);
 313                        ret = 0;
 314                }
 315        }
 316        strlist__delete(namelist);
 317
 318        return ret;
 319}
 320
 321int 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
 334int 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 */
 354static 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
 366static struct probe_cache_entry *
 367probe_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
 389int 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 */
 415static 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                strncpy(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);
 459found:
 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
 475static 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                        strlist__add(entry->tevlist, buf);
 523                }
 524        }
 525out:
 526        fclose(fp);
 527        return ret;
 528}
 529
 530static struct probe_cache *probe_cache__alloc(void)
 531{
 532        struct probe_cache *pcache = zalloc(sizeof(*pcache));
 533
 534        if (pcache) {
 535                INIT_LIST_HEAD(&pcache->entries);
 536                pcache->fd = -EINVAL;
 537        }
 538        return pcache;
 539}
 540
 541void probe_cache__purge(struct probe_cache *pcache)
 542{
 543        struct probe_cache_entry *entry, *n;
 544
 545        list_for_each_entry_safe(entry, n, &pcache->entries, node) {
 546                list_del_init(&entry->node);
 547                probe_cache_entry__delete(entry);
 548        }
 549}
 550
 551void probe_cache__delete(struct probe_cache *pcache)
 552{
 553        if (!pcache)
 554                return;
 555
 556        probe_cache__purge(pcache);
 557        if (pcache->fd > 0)
 558                close(pcache->fd);
 559        free(pcache);
 560}
 561
 562struct probe_cache *probe_cache__new(const char *target, struct nsinfo *nsi)
 563{
 564        struct probe_cache *pcache = probe_cache__alloc();
 565        int ret;
 566
 567        if (!pcache)
 568                return NULL;
 569
 570        ret = probe_cache__open(pcache, target, nsi);
 571        if (ret < 0) {
 572                pr_debug("Cache open error: %d\n", ret);
 573                goto out_err;
 574        }
 575
 576        ret = probe_cache__load(pcache);
 577        if (ret < 0) {
 578                pr_debug("Cache read error: %d\n", ret);
 579                goto out_err;
 580        }
 581
 582        return pcache;
 583
 584out_err:
 585        probe_cache__delete(pcache);
 586        return NULL;
 587}
 588
 589static bool streql(const char *a, const char *b)
 590{
 591        if (a == b)
 592                return true;
 593
 594        if (!a || !b)
 595                return false;
 596
 597        return !strcmp(a, b);
 598}
 599
 600struct probe_cache_entry *
 601probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 602{
 603        struct probe_cache_entry *entry = NULL;
 604        char *cmd = synthesize_perf_probe_command(pev);
 605
 606        if (!cmd)
 607                return NULL;
 608
 609        for_each_probe_cache_entry(entry, pcache) {
 610                if (pev->sdt) {
 611                        if (entry->pev.event &&
 612                            streql(entry->pev.event, pev->event) &&
 613                            (!pev->group ||
 614                             streql(entry->pev.group, pev->group)))
 615                                goto found;
 616
 617                        continue;
 618                }
 619                /* Hit if same event name or same command-string */
 620                if ((pev->event &&
 621                     (streql(entry->pev.group, pev->group) &&
 622                      streql(entry->pev.event, pev->event))) ||
 623                    (!strcmp(entry->spev, cmd)))
 624                        goto found;
 625        }
 626        entry = NULL;
 627
 628found:
 629        free(cmd);
 630        return entry;
 631}
 632
 633struct probe_cache_entry *
 634probe_cache__find_by_name(struct probe_cache *pcache,
 635                          const char *group, const char *event)
 636{
 637        struct probe_cache_entry *entry = NULL;
 638
 639        for_each_probe_cache_entry(entry, pcache) {
 640                /* Hit if same event name or same command-string */
 641                if (streql(entry->pev.group, group) &&
 642                    streql(entry->pev.event, event))
 643                        goto found;
 644        }
 645        entry = NULL;
 646
 647found:
 648        return entry;
 649}
 650
 651int probe_cache__add_entry(struct probe_cache *pcache,
 652                           struct perf_probe_event *pev,
 653                           struct probe_trace_event *tevs, int ntevs)
 654{
 655        struct probe_cache_entry *entry = NULL;
 656        char *command;
 657        int i, ret = 0;
 658
 659        if (!pcache || !pev || !tevs || ntevs <= 0) {
 660                ret = -EINVAL;
 661                goto out_err;
 662        }
 663
 664        /* Remove old cache entry */
 665        entry = probe_cache__find(pcache, pev);
 666        if (entry) {
 667                list_del_init(&entry->node);
 668                probe_cache_entry__delete(entry);
 669        }
 670
 671        ret = -ENOMEM;
 672        entry = probe_cache_entry__new(pev);
 673        if (!entry)
 674                goto out_err;
 675
 676        for (i = 0; i < ntevs; i++) {
 677                if (!tevs[i].point.symbol)
 678                        continue;
 679
 680                command = synthesize_probe_trace_command(&tevs[i]);
 681                if (!command)
 682                        goto out_err;
 683                strlist__add(entry->tevlist, command);
 684                free(command);
 685        }
 686        list_add_tail(&entry->node, &pcache->entries);
 687        pr_debug("Added probe cache: %d\n", ntevs);
 688        return 0;
 689
 690out_err:
 691        pr_debug("Failed to add probe caches\n");
 692        probe_cache_entry__delete(entry);
 693        return ret;
 694}
 695
 696#ifdef HAVE_GELF_GETNOTE_SUPPORT
 697static unsigned long long sdt_note__get_addr(struct sdt_note *note)
 698{
 699        return note->bit32 ? (unsigned long long)note->addr.a32[0]
 700                 : (unsigned long long)note->addr.a64[0];
 701}
 702
 703static const char * const type_to_suffix[] = {
 704        ":s64", "", "", "", ":s32", "", ":s16", ":s8",
 705        "", ":u8", ":u16", "", ":u32", "", "", "", ":u64"
 706};
 707
 708/*
 709 * Isolate the string number and convert it into a decimal value;
 710 * this will be an index to get suffix of the uprobe name (defining
 711 * the type)
 712 */
 713static int sdt_arg_parse_size(char *n_ptr, const char **suffix)
 714{
 715        long type_idx;
 716
 717        type_idx = strtol(n_ptr, NULL, 10);
 718        if (type_idx < -8 || type_idx > 8) {
 719                pr_debug4("Failed to get a valid sdt type\n");
 720                return -1;
 721        }
 722
 723        *suffix = type_to_suffix[type_idx + 8];
 724        return 0;
 725}
 726
 727static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg)
 728{
 729        char *op, *desc = strdup(arg), *new_op = NULL;
 730        const char *suffix = "";
 731        int ret = -1;
 732
 733        if (desc == NULL) {
 734                pr_debug4("Allocation error\n");
 735                return ret;
 736        }
 737
 738        /*
 739         * Argument is in N@OP format. N is size of the argument and OP is
 740         * the actual assembly operand. N can be omitted; in that case
 741         * argument is just OP(without @).
 742         */
 743        op = strchr(desc, '@');
 744        if (op) {
 745                op[0] = '\0';
 746                op++;
 747
 748                if (sdt_arg_parse_size(desc, &suffix))
 749                        goto error;
 750        } else {
 751                op = desc;
 752        }
 753
 754        ret = arch_sdt_arg_parse_op(op, &new_op);
 755
 756        if (ret < 0)
 757                goto error;
 758
 759        if (ret == SDT_ARG_VALID) {
 760                ret = strbuf_addf(buf, " arg%d=%s%s", i + 1, new_op, suffix);
 761                if (ret < 0)
 762                        goto error;
 763        }
 764
 765        ret = 0;
 766error:
 767        free(desc);
 768        free(new_op);
 769        return ret;
 770}
 771
 772static char *synthesize_sdt_probe_command(struct sdt_note *note,
 773                                        const char *pathname,
 774                                        const char *sdtgrp)
 775{
 776        struct strbuf buf;
 777        char *ret = NULL, **args;
 778        int i, args_count;
 779
 780        if (strbuf_init(&buf, 32) < 0)
 781                return NULL;
 782
 783        if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
 784                                sdtgrp, note->name, pathname,
 785                                sdt_note__get_addr(note)) < 0)
 786                goto error;
 787
 788        if (!note->args)
 789                goto out;
 790
 791        if (note->args) {
 792                args = argv_split(note->args, &args_count);
 793
 794                for (i = 0; i < args_count; ++i) {
 795                        if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0)
 796                                goto error;
 797                }
 798        }
 799
 800out:
 801        ret = strbuf_detach(&buf, NULL);
 802error:
 803        strbuf_release(&buf);
 804        return ret;
 805}
 806
 807int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname)
 808{
 809        struct probe_cache_entry *entry = NULL;
 810        struct list_head sdtlist;
 811        struct sdt_note *note;
 812        char *buf;
 813        char sdtgrp[64];
 814        int ret;
 815
 816        INIT_LIST_HEAD(&sdtlist);
 817        ret = get_sdt_note_list(&sdtlist, pathname);
 818        if (ret < 0) {
 819                pr_debug4("Failed to get sdt note: %d\n", ret);
 820                return ret;
 821        }
 822        list_for_each_entry(note, &sdtlist, note_list) {
 823                ret = snprintf(sdtgrp, 64, "sdt_%s", note->provider);
 824                if (ret < 0)
 825                        break;
 826                /* Try to find same-name entry */
 827                entry = probe_cache__find_by_name(pcache, sdtgrp, note->name);
 828                if (!entry) {
 829                        entry = probe_cache_entry__new(NULL);
 830                        if (!entry) {
 831                                ret = -ENOMEM;
 832                                break;
 833                        }
 834                        entry->sdt = true;
 835                        ret = asprintf(&entry->spev, "%s:%s=%s", sdtgrp,
 836                                        note->name, note->name);
 837                        if (ret < 0)
 838                                break;
 839                        entry->pev.event = strdup(note->name);
 840                        entry->pev.group = strdup(sdtgrp);
 841                        list_add_tail(&entry->node, &pcache->entries);
 842                }
 843                buf = synthesize_sdt_probe_command(note, pathname, sdtgrp);
 844                if (!buf) {
 845                        ret = -ENOMEM;
 846                        break;
 847                }
 848
 849                strlist__add(entry->tevlist, buf);
 850                free(buf);
 851                entry = NULL;
 852        }
 853        if (entry) {
 854                list_del_init(&entry->node);
 855                probe_cache_entry__delete(entry);
 856        }
 857        cleanup_sdt_note_list(&sdtlist);
 858        return ret;
 859}
 860#endif
 861
 862static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd)
 863{
 864        struct str_node *snode;
 865        struct stat st;
 866        struct iovec iov[3];
 867        const char *prefix = entry->sdt ? "%" : "#";
 868        int ret;
 869        /* Save stat for rollback */
 870        ret = fstat(fd, &st);
 871        if (ret < 0)
 872                return ret;
 873
 874        pr_debug("Writing cache: %s%s\n", prefix, entry->spev);
 875        iov[0].iov_base = (void *)prefix; iov[0].iov_len = 1;
 876        iov[1].iov_base = entry->spev; iov[1].iov_len = strlen(entry->spev);
 877        iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1;
 878        ret = writev(fd, iov, 3);
 879        if (ret < (int)iov[1].iov_len + 2)
 880                goto rollback;
 881
 882        strlist__for_each_entry(snode, entry->tevlist) {
 883                iov[0].iov_base = (void *)snode->s;
 884                iov[0].iov_len = strlen(snode->s);
 885                iov[1].iov_base = (void *)"\n"; iov[1].iov_len = 1;
 886                ret = writev(fd, iov, 2);
 887                if (ret < (int)iov[0].iov_len + 1)
 888                        goto rollback;
 889        }
 890        return 0;
 891
 892rollback:
 893        /* Rollback to avoid cache file corruption */
 894        if (ret > 0)
 895                ret = -1;
 896        if (ftruncate(fd, st.st_size) < 0)
 897                ret = -2;
 898
 899        return ret;
 900}
 901
 902int probe_cache__commit(struct probe_cache *pcache)
 903{
 904        struct probe_cache_entry *entry;
 905        int ret = 0;
 906
 907        /* TBD: if we do not update existing entries, skip it */
 908        ret = lseek(pcache->fd, 0, SEEK_SET);
 909        if (ret < 0)
 910                goto out;
 911
 912        ret = ftruncate(pcache->fd, 0);
 913        if (ret < 0)
 914                goto out;
 915
 916        for_each_probe_cache_entry(entry, pcache) {
 917                ret = probe_cache_entry__write(entry, pcache->fd);
 918                pr_debug("Cache committed: %d\n", ret);
 919                if (ret < 0)
 920                        break;
 921        }
 922out:
 923        return ret;
 924}
 925
 926static bool probe_cache_entry__compare(struct probe_cache_entry *entry,
 927                                       struct strfilter *filter)
 928{
 929        char buf[128], *ptr = entry->spev;
 930
 931        if (entry->pev.event) {
 932                snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event);
 933                ptr = buf;
 934        }
 935        return strfilter__compare(filter, ptr);
 936}
 937
 938int probe_cache__filter_purge(struct probe_cache *pcache,
 939                              struct strfilter *filter)
 940{
 941        struct probe_cache_entry *entry, *tmp;
 942
 943        list_for_each_entry_safe(entry, tmp, &pcache->entries, node) {
 944                if (probe_cache_entry__compare(entry, filter)) {
 945                        pr_info("Removed cached event: %s\n", entry->spev);
 946                        list_del_init(&entry->node);
 947                        probe_cache_entry__delete(entry);
 948                }
 949        }
 950        return 0;
 951}
 952
 953static int probe_cache__show_entries(struct probe_cache *pcache,
 954                                     struct strfilter *filter)
 955{
 956        struct probe_cache_entry *entry;
 957
 958        for_each_probe_cache_entry(entry, pcache) {
 959                if (probe_cache_entry__compare(entry, filter))
 960                        printf("%s\n", entry->spev);
 961        }
 962        return 0;
 963}
 964
 965/* Show all cached probes */
 966int probe_cache__show_all_caches(struct strfilter *filter)
 967{
 968        struct probe_cache *pcache;
 969        struct strlist *bidlist;
 970        struct str_node *nd;
 971        char *buf = strfilter__string(filter);
 972
 973        pr_debug("list cache with filter: %s\n", buf);
 974        free(buf);
 975
 976        bidlist = build_id_cache__list_all(true);
 977        if (!bidlist) {
 978                pr_debug("Failed to get buildids: %d\n", errno);
 979                return -EINVAL;
 980        }
 981        strlist__for_each_entry(nd, bidlist) {
 982                pcache = probe_cache__new(nd->s, NULL);
 983                if (!pcache)
 984                        continue;
 985                if (!list_empty(&pcache->entries)) {
 986                        buf = build_id_cache__origname(nd->s);
 987                        printf("%s (%s):\n", buf, nd->s);
 988                        free(buf);
 989                        probe_cache__show_entries(pcache, filter);
 990                }
 991                probe_cache__delete(pcache);
 992        }
 993        strlist__delete(bidlist);
 994
 995        return 0;
 996}
 997
 998enum ftrace_readme {
 999        FTRACE_README_PROBE_TYPE_X = 0,
1000        FTRACE_README_KRETPROBE_OFFSET,
1001        FTRACE_README_END,
1002};
1003
1004static struct {
1005        const char *pattern;
1006        bool avail;
1007} ftrace_readme_table[] = {
1008#define DEFINE_TYPE(idx, pat)                   \
1009        [idx] = {.pattern = pat, .avail = false}
1010        DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
1011        DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
1012};
1013
1014static bool scan_ftrace_readme(enum ftrace_readme type)
1015{
1016        int fd;
1017        FILE *fp;
1018        char *buf = NULL;
1019        size_t len = 0;
1020        bool ret = false;
1021        static bool scanned = false;
1022
1023        if (scanned)
1024                goto result;
1025
1026        fd = open_trace_file("README", false);
1027        if (fd < 0)
1028                return ret;
1029
1030        fp = fdopen(fd, "r");
1031        if (!fp) {
1032                close(fd);
1033                return ret;
1034        }
1035
1036        while (getline(&buf, &len, fp) > 0)
1037                for (enum ftrace_readme i = 0; i < FTRACE_README_END; i++)
1038                        if (!ftrace_readme_table[i].avail)
1039                                ftrace_readme_table[i].avail =
1040                                        strglobmatch(buf, ftrace_readme_table[i].pattern);
1041        scanned = true;
1042
1043        fclose(fp);
1044        free(buf);
1045
1046result:
1047        if (type >= FTRACE_README_END)
1048                return false;
1049
1050        return ftrace_readme_table[type].avail;
1051}
1052
1053bool probe_type_is_available(enum probe_type type)
1054{
1055        if (type >= PROBE_TYPE_END)
1056                return false;
1057        else if (type == PROBE_TYPE_X)
1058                return scan_ftrace_readme(FTRACE_README_PROBE_TYPE_X);
1059
1060        return true;
1061}
1062
1063bool kretprobe_offset_is_supported(void)
1064{
1065        return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
1066}
1067