struct tracing_data *tracing_data_get(struct list_head *pattrs, int fd, bool temp) { struct tracepoint_path *tps; struct tracing_data *tdata; output_fd = fd; tps = get_tracepoints_path(pattrs); if (!tps) return NULL; tdata = malloc_or_die(sizeof(*tdata)); tdata->temp = temp; tdata->size = 0; if (temp) { int temp_fd; snprintf(tdata->temp_file, sizeof(tdata->temp_file), "/tmp/perf-XXXXXX"); if (!mkstemp(tdata->temp_file)) die("Can't make temp file"); temp_fd = open(tdata->temp_file, O_RDWR); if (temp_fd < 0) die("Can't read '%s'", tdata->temp_file); /* * Set the temp file the default output, so all the * tracing data are stored into it. */ output_fd = temp_fd; } tracing_data_header(); read_header_files(); read_ftrace_files(tps); read_event_files(tps); read_proc_kallsyms(); read_ftrace_printk(); /* * All tracing data are stored by now, we can restore * the default output file in case we used temp file. */ if (temp) { tdata->size = lseek(output_fd, 0, SEEK_CUR); close(output_fd); output_fd = fd; } put_tracepoints_path(tps); return tdata; }
static struct tracepoint_path * get_tracepoints_path(struct list_head *pattrs) { struct tracepoint_path path, *ppath = &path; struct perf_evsel *pos; int nr_tracepoints = 0; list_for_each_entry(pos, pattrs, node) { if (pos->attr.type != PERF_TYPE_TRACEPOINT) continue; ++nr_tracepoints; if (pos->name) { ppath->next = tracepoint_name_to_path(pos->name); if (ppath->next) goto next; if (strchr(pos->name, ':') == NULL) goto try_id; goto error; } try_id: ppath->next = tracepoint_id_to_path(pos->attr.config); if (!ppath->next) { error: pr_debug("No memory to alloc tracepoints list\n"); put_tracepoints_path(&path); return NULL; } next: ppath = ppath->next; } return nr_tracepoints > 0 ? path.next : NULL; }