1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/compiler.h> 3 #include <linux/kernel.h> 4 #include <linux/string.h> 5 #include <linux/zalloc.h> 6 #include <linux/err.h> 7 #include <sys/types.h> 8 #include <sys/stat.h> 9 #include <errno.h> 10 #include <fcntl.h> 11 #include <unistd.h> 12 #include <string.h> 13 #include <asm/bug.h> 14 #include <dirent.h> 15 16 #include "data.h" 17 #include "util.h" // rm_rf_perf_data() 18 #include "debug.h" 19 #include "header.h" 20 #include "rlimit.h" 21 #include <internal/lib.h> 22 23 static void close_dir(struct perf_data_file *files, int nr) 24 { 25 while (--nr >= 0) { 26 close(files[nr].fd); 27 zfree(&files[nr].path); 28 } 29 free(files); 30 } 31 32 void perf_data__close_dir(struct perf_data *data) 33 { 34 close_dir(data->dir.files, data->dir.nr); 35 } 36 37 int perf_data__create_dir(struct perf_data *data, int nr) 38 { 39 enum rlimit_action set_rlimit = NO_CHANGE; 40 struct perf_data_file *files = NULL; 41 int i, ret; 42 43 if (WARN_ON(!data->is_dir)) 44 return -EINVAL; 45 46 files = zalloc(nr * sizeof(*files)); 47 if (!files) 48 return -ENOMEM; 49 50 for (i = 0; i < nr; i++) { 51 struct perf_data_file *file = &files[i]; 52 53 ret = asprintf(&file->path, "%s/data.%d", data->path, i); 54 if (ret < 0) { 55 ret = -ENOMEM; 56 goto out_err; 57 } 58 59 retry_open: 60 ret = open(file->path, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); 61 if (ret < 0) { 62 /* 63 * If using parallel threads to collect data, 64 * perf record needs at least 6 fds per CPU. 65 * When we run out of them try to increase the limits. 66 */ 67 if (errno == EMFILE && rlimit__increase_nofile(&set_rlimit)) 68 goto retry_open; 69 70 ret = -errno; 71 goto out_err; 72 } 73 set_rlimit = NO_CHANGE; 74 75 file->fd = ret; 76 } 77 78 data->dir.version = PERF_DIR_VERSION; 79 data->dir.files = files; 80 data->dir.nr = nr; 81 return 0; 82 83 out_err: 84 close_dir(files, i); 85 return ret; 86 } 87 88 int perf_data__open_dir(struct perf_data *data) 89 { 90 struct perf_data_file *files = NULL; 91 struct dirent *dent; 92 int ret = -1; 93 DIR *dir; 94 int nr = 0; 95 96 /* 97 * Directory containing a single regular perf data file which is already 98 * open, means there is nothing more to do here. 99 */ 100 if (perf_data__is_single_file(data)) 101 return 0; 102 103 if (WARN_ON(!data->is_dir)) 104 return -EINVAL; 105 106 /* The version is provided by DIR_FORMAT feature. */ 107 if (WARN_ON(data->dir.version != PERF_DIR_VERSION)) 108 return -1; 109 110 dir = opendir(data->path); 111 if (!dir) 112 return -EINVAL; 113 114 while ((dent = readdir(dir)) != NULL) { 115 struct perf_data_file *file; 116 char path[PATH_MAX]; 117 struct stat st; 118 119 snprintf(path, sizeof(path), "%s/%s", data->path, dent->d_name); 120 if (stat(path, &st)) 121 continue; 122 123 if (!S_ISREG(st.st_mode) || strncmp(dent->d_name, "data.", 5)) 124 continue; 125 126 ret = -ENOMEM; 127 128 file = realloc(files, (nr + 1) * sizeof(*files)); 129 if (!file) 130 goto out_err; 131 132 files = file; 133 file = &files[nr++]; 134 135 file->path = strdup(path); 136 if (!file->path) 137 goto out_err; 138 139 ret = open(file->path, O_RDONLY); 140 if (ret < 0) 141 goto out_err; 142 143 file->fd = ret; 144 file->size = st.st_size; 145 } 146 147 closedir(dir); 148 if (!files) 149 return -EINVAL; 150 151 data->dir.files = files; 152 data->dir.nr = nr; 153 return 0; 154 155 out_err: 156 closedir(dir); 157 close_dir(files, nr); 158 return ret; 159 } 160 161 static bool check_pipe(struct perf_data *data) 162 { 163 struct stat st; 164 bool is_pipe = false; 165 int fd = perf_data__is_read(data) ? 166 STDIN_FILENO : STDOUT_FILENO; 167 168 if (!data->path) { 169 if (!fstat(fd, &st) && S_ISFIFO(st.st_mode)) 170 is_pipe = true; 171 } else { 172 if (!strcmp(data->path, "-")) 173 is_pipe = true; 174 } 175 176 if (is_pipe) { 177 if (data->use_stdio) { 178 const char *mode; 179 180 mode = perf_data__is_read(data) ? "r" : "w"; 181 data->file.fptr = fdopen(fd, mode); 182 183 if (data->file.fptr == NULL) { 184 data->file.fd = fd; 185 data->use_stdio = false; 186 } 187 188 /* 189 * When is_pipe and data->file.fd is given, use given fd 190 * instead of STDIN_FILENO or STDOUT_FILENO 191 */ 192 } else if (data->file.fd <= 0) { 193 data->file.fd = fd; 194 } 195 } 196 197 return data->is_pipe = is_pipe; 198 } 199 200 static int check_backup(struct perf_data *data) 201 { 202 struct stat st; 203 204 if (perf_data__is_read(data)) 205 return 0; 206 207 if (!stat(data->path, &st) && st.st_size) { 208 char oldname[PATH_MAX]; 209 int ret; 210 211 snprintf(oldname, sizeof(oldname), "%s.old", 212 data->path); 213 214 ret = rm_rf_perf_data(oldname); 215 if (ret) { 216 pr_err("Can't remove old data: %s (%s)\n", 217 ret == -2 ? 218 "Unknown file found" : strerror(errno), 219 oldname); 220 return -1; 221 } 222 223 if (rename(data->path, oldname)) { 224 pr_err("Can't move data: %s (%s to %s)\n", 225 strerror(errno), 226 data->path, oldname); 227 return -1; 228 } 229 } 230 231 return 0; 232 } 233 234 static bool is_dir(struct perf_data *data) 235 { 236 struct stat st; 237 238 if (stat(data->path, &st)) 239 return false; 240 241 return (st.st_mode & S_IFMT) == S_IFDIR; 242 } 243 244 static int open_file_read(struct perf_data *data) 245 { 246 int flags = data->in_place_update ? O_RDWR : O_RDONLY; 247 struct stat st; 248 int fd; 249 char sbuf[STRERR_BUFSIZE]; 250 251 fd = open(data->file.path, flags); 252 if (fd < 0) { 253 int err = errno; 254 255 pr_err("failed to open %s: %s", data->file.path, 256 str_error_r(err, sbuf, sizeof(sbuf))); 257 if (err == ENOENT && !strcmp(data->file.path, "perf.data")) 258 pr_err(" (try 'perf record' first)"); 259 pr_err("\n"); 260 return -err; 261 } 262 263 if (fstat(fd, &st) < 0) 264 goto out_close; 265 266 if (!data->force && st.st_uid && (st.st_uid != geteuid())) { 267 pr_err("File %s not owned by current user or root (use -f to override)\n", 268 data->file.path); 269 goto out_close; 270 } 271 272 if (!st.st_size) { 273 pr_info("zero-sized data (%s), nothing to do!\n", 274 data->file.path); 275 goto out_close; 276 } 277 278 data->file.size = st.st_size; 279 return fd; 280 281 out_close: 282 close(fd); 283 return -1; 284 } 285 286 static int open_file_write(struct perf_data *data) 287 { 288 int fd; 289 char sbuf[STRERR_BUFSIZE]; 290 291 fd = open(data->file.path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 292 S_IRUSR|S_IWUSR); 293 294 if (fd < 0) 295 pr_err("failed to open %s : %s\n", data->file.path, 296 str_error_r(errno, sbuf, sizeof(sbuf))); 297 298 return fd; 299 } 300 301 static int open_file(struct perf_data *data) 302 { 303 int fd; 304 305 fd = perf_data__is_read(data) ? 306 open_file_read(data) : open_file_write(data); 307 308 if (fd < 0) { 309 zfree(&data->file.path); 310 return -1; 311 } 312 313 data->file.fd = fd; 314 return 0; 315 } 316 317 static int open_file_dup(struct perf_data *data) 318 { 319 data->file.path = strdup(data->path); 320 if (!data->file.path) 321 return -ENOMEM; 322 323 return open_file(data); 324 } 325 326 static int open_dir(struct perf_data *data) 327 { 328 int ret; 329 330 /* 331 * So far we open only the header, so we can read the data version and 332 * layout. 333 */ 334 if (asprintf(&data->file.path, "%s/data", data->path) < 0) 335 return -1; 336 337 if (perf_data__is_write(data) && 338 mkdir(data->path, S_IRWXU) < 0) 339 return -1; 340 341 ret = open_file(data); 342 343 /* Cleanup whatever we managed to create so far. */ 344 if (ret && perf_data__is_write(data)) 345 rm_rf_perf_data(data->path); 346 347 return ret; 348 } 349 350 int perf_data__open(struct perf_data *data) 351 { 352 if (check_pipe(data)) 353 return 0; 354 355 /* currently it allows stdio for pipe only */ 356 data->use_stdio = false; 357 358 if (!data->path) 359 data->path = "perf.data"; 360 361 if (check_backup(data)) 362 return -1; 363 364 if (perf_data__is_read(data)) 365 data->is_dir = is_dir(data); 366 367 return perf_data__is_dir(data) ? 368 open_dir(data) : open_file_dup(data); 369 } 370 371 void perf_data__close(struct perf_data *data) 372 { 373 if (perf_data__is_dir(data)) 374 perf_data__close_dir(data); 375 376 zfree(&data->file.path); 377 378 if (data->use_stdio) 379 fclose(data->file.fptr); 380 else 381 close(data->file.fd); 382 } 383 384 ssize_t perf_data__read(struct perf_data *data, void *buf, size_t size) 385 { 386 if (data->use_stdio) { 387 if (fread(buf, size, 1, data->file.fptr) == 1) 388 return size; 389 return feof(data->file.fptr) ? 0 : -1; 390 } 391 return readn(data->file.fd, buf, size); 392 } 393 394 ssize_t perf_data_file__write(struct perf_data_file *file, 395 void *buf, size_t size) 396 { 397 return writen(file->fd, buf, size); 398 } 399 400 ssize_t perf_data__write(struct perf_data *data, 401 void *buf, size_t size) 402 { 403 if (data->use_stdio) { 404 if (fwrite(buf, size, 1, data->file.fptr) == 1) 405 return size; 406 return -1; 407 } 408 return perf_data_file__write(&data->file, buf, size); 409 } 410 411 int perf_data__switch(struct perf_data *data, 412 const char *postfix, 413 size_t pos, bool at_exit, 414 char **new_filepath) 415 { 416 int ret; 417 418 if (perf_data__is_read(data)) 419 return -EINVAL; 420 421 if (asprintf(new_filepath, "%s.%s", data->path, postfix) < 0) 422 return -ENOMEM; 423 424 /* 425 * Only fire a warning, don't return error, continue fill 426 * original file. 427 */ 428 if (rename(data->path, *new_filepath)) 429 pr_warning("Failed to rename %s to %s\n", data->path, *new_filepath); 430 431 if (!at_exit) { 432 close(data->file.fd); 433 ret = perf_data__open(data); 434 if (ret < 0) 435 goto out; 436 437 if (lseek(data->file.fd, pos, SEEK_SET) == (off_t)-1) { 438 ret = -errno; 439 pr_debug("Failed to lseek to %zu: %s", 440 pos, strerror(errno)); 441 goto out; 442 } 443 } 444 ret = data->file.fd; 445 out: 446 return ret; 447 } 448 449 unsigned long perf_data__size(struct perf_data *data) 450 { 451 u64 size = data->file.size; 452 int i; 453 454 if (perf_data__is_single_file(data)) 455 return size; 456 457 for (i = 0; i < data->dir.nr; i++) { 458 struct perf_data_file *file = &data->dir.files[i]; 459 460 size += file->size; 461 } 462 463 return size; 464 } 465 466 int perf_data__make_kcore_dir(struct perf_data *data, char *buf, size_t buf_sz) 467 { 468 int ret; 469 470 if (!data->is_dir) 471 return -1; 472 473 ret = snprintf(buf, buf_sz, "%s/kcore_dir", data->path); 474 if (ret < 0 || (size_t)ret >= buf_sz) 475 return -1; 476 477 return mkdir(buf, S_IRWXU); 478 } 479 480 bool has_kcore_dir(const char *path) 481 { 482 struct dirent *d = ERR_PTR(-EINVAL); 483 const char *name = "kcore_dir"; 484 DIR *dir = opendir(path); 485 size_t n = strlen(name); 486 bool result = false; 487 488 if (dir) { 489 while (d && !result) { 490 d = readdir(dir); 491 result = d ? strncmp(d->d_name, name, n) : false; 492 } 493 closedir(dir); 494 } 495 496 return result; 497 } 498 499 char *perf_data__kallsyms_name(struct perf_data *data) 500 { 501 char *kallsyms_name; 502 struct stat st; 503 504 if (!data->is_dir) 505 return NULL; 506 507 if (asprintf(&kallsyms_name, "%s/kcore_dir/kallsyms", data->path) < 0) 508 return NULL; 509 510 if (stat(kallsyms_name, &st)) { 511 free(kallsyms_name); 512 return NULL; 513 } 514 515 return kallsyms_name; 516 } 517 518 char *perf_data__guest_kallsyms_name(struct perf_data *data, pid_t machine_pid) 519 { 520 char *kallsyms_name; 521 struct stat st; 522 523 if (!data->is_dir) 524 return NULL; 525 526 if (asprintf(&kallsyms_name, "%s/kcore_dir__%d/kallsyms", data->path, machine_pid) < 0) 527 return NULL; 528 529 if (stat(kallsyms_name, &st)) { 530 free(kallsyms_name); 531 return NULL; 532 } 533 534 return kallsyms_name; 535 } 536 537 bool is_perf_data(const char *path) 538 { 539 bool ret = false; 540 FILE *file; 541 u64 magic; 542 543 file = fopen(path, "r"); 544 if (!file) 545 return false; 546 547 if (fread(&magic, 1, 8, file) < 8) 548 goto out; 549 550 ret = is_perf_magic(magic); 551 out: 552 fclose(file); 553 return ret; 554 } 555