data.c 10 KB

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