diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-09-24 14:14:12 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-09-25 08:51:49 -0400 |
commit | 32ff3fec07b6d8e6c5cc2342f6cbbdcb224d484c (patch) | |
tree | 7b4ecd5ec18e1c0c07f74fb3b6486c66f24f2d5e | |
parent | 80ab2987a016f774201d4f3509118047f9d58175 (diff) |
perf copyfile: Move copyfile routines to separate files
Further reducing the util.c hodgepodge files.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lkml.kernel.org/n/tip-0i62zh7ok25znibyebgq0qs4@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/Build | 1 | ||||
-rw-r--r-- | tools/perf/util/build-id.c | 3 | ||||
-rw-r--r-- | tools/perf/util/copyfile.c | 144 | ||||
-rw-r--r-- | tools/perf/util/copyfile.h | 16 | ||||
-rw-r--r-- | tools/perf/util/symbol-elf.c | 2 | ||||
-rw-r--r-- | tools/perf/util/util.c | 135 | ||||
-rw-r--r-- | tools/perf/util/util.h | 5 |
7 files changed, 164 insertions, 142 deletions
diff --git a/tools/perf/util/Build b/tools/perf/util/Build index fd89d6a8cd65..4d1894e38a81 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build | |||
@@ -3,6 +3,7 @@ perf-y += block-range.o | |||
3 | perf-y += build-id.o | 3 | perf-y += build-id.o |
4 | perf-y += cacheline.o | 4 | perf-y += cacheline.o |
5 | perf-y += config.o | 5 | perf-y += config.o |
6 | perf-y += copyfile.o | ||
6 | perf-y += ctype.o | 7 | perf-y += ctype.o |
7 | perf-y += db-export.o | 8 | perf-y += db-export.o |
8 | perf-y += env.o | 9 | perf-y += env.o |
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 7928c398a063..c076fc7fe025 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
@@ -7,12 +7,13 @@ | |||
7 | * Copyright (C) 2009, 2010 Red Hat Inc. | 7 | * Copyright (C) 2009, 2010 Red Hat Inc. |
8 | * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo <acme@redhat.com> | 8 | * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo <acme@redhat.com> |
9 | */ | 9 | */ |
10 | #include "util.h" // copyfile_ns(), lsdir(), mkdir_p(), rm_rf() | 10 | #include "util.h" // lsdir(), mkdir_p(), rm_rf() |
11 | #include <dirent.h> | 11 | #include <dirent.h> |
12 | #include <errno.h> | 12 | #include <errno.h> |
13 | #include <stdio.h> | 13 | #include <stdio.h> |
14 | #include <sys/stat.h> | 14 | #include <sys/stat.h> |
15 | #include <sys/types.h> | 15 | #include <sys/types.h> |
16 | #include "util/copyfile.h" | ||
16 | #include "dso.h" | 17 | #include "dso.h" |
17 | #include "build-id.h" | 18 | #include "build-id.h" |
18 | #include "event.h" | 19 | #include "event.h" |
diff --git a/tools/perf/util/copyfile.c b/tools/perf/util/copyfile.c new file mode 100644 index 000000000000..3fa0db136667 --- /dev/null +++ b/tools/perf/util/copyfile.c | |||
@@ -0,0 +1,144 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include "util/copyfile.h" | ||
3 | #include "util/namespaces.h" | ||
4 | #include <internal/lib.h> | ||
5 | #include <sys/mman.h> | ||
6 | #include <sys/stat.h> | ||
7 | #include <errno.h> | ||
8 | #include <fcntl.h> | ||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <string.h> | ||
12 | #include <unistd.h> | ||
13 | |||
14 | static int slow_copyfile(const char *from, const char *to, struct nsinfo *nsi) | ||
15 | { | ||
16 | int err = -1; | ||
17 | char *line = NULL; | ||
18 | size_t n; | ||
19 | FILE *from_fp, *to_fp; | ||
20 | struct nscookie nsc; | ||
21 | |||
22 | nsinfo__mountns_enter(nsi, &nsc); | ||
23 | from_fp = fopen(from, "r"); | ||
24 | nsinfo__mountns_exit(&nsc); | ||
25 | if (from_fp == NULL) | ||
26 | goto out; | ||
27 | |||
28 | to_fp = fopen(to, "w"); | ||
29 | if (to_fp == NULL) | ||
30 | goto out_fclose_from; | ||
31 | |||
32 | while (getline(&line, &n, from_fp) > 0) | ||
33 | if (fputs(line, to_fp) == EOF) | ||
34 | goto out_fclose_to; | ||
35 | err = 0; | ||
36 | out_fclose_to: | ||
37 | fclose(to_fp); | ||
38 | free(line); | ||
39 | out_fclose_from: | ||
40 | fclose(from_fp); | ||
41 | out: | ||
42 | return err; | ||
43 | } | ||
44 | |||
45 | int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) | ||
46 | { | ||
47 | void *ptr; | ||
48 | loff_t pgoff; | ||
49 | |||
50 | pgoff = off_in & ~(page_size - 1); | ||
51 | off_in -= pgoff; | ||
52 | |||
53 | ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff); | ||
54 | if (ptr == MAP_FAILED) | ||
55 | return -1; | ||
56 | |||
57 | while (size) { | ||
58 | ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out); | ||
59 | if (ret < 0 && errno == EINTR) | ||
60 | continue; | ||
61 | if (ret <= 0) | ||
62 | break; | ||
63 | |||
64 | size -= ret; | ||
65 | off_in += ret; | ||
66 | off_out += ret; | ||
67 | } | ||
68 | munmap(ptr, off_in + size); | ||
69 | |||
70 | return size ? -1 : 0; | ||
71 | } | ||
72 | |||
73 | static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, | ||
74 | struct nsinfo *nsi) | ||
75 | { | ||
76 | int fromfd, tofd; | ||
77 | struct stat st; | ||
78 | int err; | ||
79 | char *tmp = NULL, *ptr = NULL; | ||
80 | struct nscookie nsc; | ||
81 | |||
82 | nsinfo__mountns_enter(nsi, &nsc); | ||
83 | err = stat(from, &st); | ||
84 | nsinfo__mountns_exit(&nsc); | ||
85 | if (err) | ||
86 | goto out; | ||
87 | err = -1; | ||
88 | |||
89 | /* extra 'x' at the end is to reserve space for '.' */ | ||
90 | if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) { | ||
91 | tmp = NULL; | ||
92 | goto out; | ||
93 | } | ||
94 | ptr = strrchr(tmp, '/'); | ||
95 | if (!ptr) | ||
96 | goto out; | ||
97 | ptr = memmove(ptr + 1, ptr, strlen(ptr) - 1); | ||
98 | *ptr = '.'; | ||
99 | |||
100 | tofd = mkstemp(tmp); | ||
101 | if (tofd < 0) | ||
102 | goto out; | ||
103 | |||
104 | if (fchmod(tofd, mode)) | ||
105 | goto out_close_to; | ||
106 | |||
107 | if (st.st_size == 0) { /* /proc? do it slowly... */ | ||
108 | err = slow_copyfile(from, tmp, nsi); | ||
109 | goto out_close_to; | ||
110 | } | ||
111 | |||
112 | nsinfo__mountns_enter(nsi, &nsc); | ||
113 | fromfd = open(from, O_RDONLY); | ||
114 | nsinfo__mountns_exit(&nsc); | ||
115 | if (fromfd < 0) | ||
116 | goto out_close_to; | ||
117 | |||
118 | err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size); | ||
119 | |||
120 | close(fromfd); | ||
121 | out_close_to: | ||
122 | close(tofd); | ||
123 | if (!err) | ||
124 | err = link(tmp, to); | ||
125 | unlink(tmp); | ||
126 | out: | ||
127 | free(tmp); | ||
128 | return err; | ||
129 | } | ||
130 | |||
131 | int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi) | ||
132 | { | ||
133 | return copyfile_mode_ns(from, to, 0755, nsi); | ||
134 | } | ||
135 | |||
136 | int copyfile_mode(const char *from, const char *to, mode_t mode) | ||
137 | { | ||
138 | return copyfile_mode_ns(from, to, mode, NULL); | ||
139 | } | ||
140 | |||
141 | int copyfile(const char *from, const char *to) | ||
142 | { | ||
143 | return copyfile_mode(from, to, 0755); | ||
144 | } | ||
diff --git a/tools/perf/util/copyfile.h b/tools/perf/util/copyfile.h new file mode 100644 index 000000000000..e85d2f22f3cc --- /dev/null +++ b/tools/perf/util/copyfile.h | |||
@@ -0,0 +1,16 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #ifndef PERF_COPYFILE_H_ | ||
3 | #define PERF_COPYFILE_H_ | ||
4 | |||
5 | #include <linux/types.h> | ||
6 | #include <sys/types.h> | ||
7 | #include <fcntl.h> | ||
8 | |||
9 | struct nsinfo; | ||
10 | |||
11 | int copyfile(const char *from, const char *to); | ||
12 | int copyfile_mode(const char *from, const char *to, mode_t mode); | ||
13 | int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi); | ||
14 | int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size); | ||
15 | |||
16 | #endif // PERF_COPYFILE_H_ | ||
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 6fbfdf8bf61f..66f4be1df573 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include "machine.h" | 17 | #include "machine.h" |
18 | #include "vdso.h" | 18 | #include "vdso.h" |
19 | #include "debug.h" | 19 | #include "debug.h" |
20 | #include "util.h" | 20 | #include "util/copyfile.h" |
21 | #include <linux/ctype.h> | 21 | #include <linux/ctype.h> |
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/zalloc.h> | 23 | #include <linux/zalloc.h> |
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index cb6fa4c98470..5eda6e19c947 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
@@ -2,10 +2,7 @@ | |||
2 | #include "util.h" | 2 | #include "util.h" |
3 | #include "debug.h" | 3 | #include "debug.h" |
4 | #include "event.h" | 4 | #include "event.h" |
5 | #include "namespaces.h" | ||
6 | #include <internal/lib.h> | ||
7 | #include <api/fs/fs.h> | 5 | #include <api/fs/fs.h> |
8 | #include <sys/mman.h> | ||
9 | #include <sys/stat.h> | 6 | #include <sys/stat.h> |
10 | #include <sys/utsname.h> | 7 | #include <sys/utsname.h> |
11 | #include <dirent.h> | 8 | #include <dirent.h> |
@@ -233,138 +230,6 @@ out: | |||
233 | return list; | 230 | return list; |
234 | } | 231 | } |
235 | 232 | ||
236 | static int slow_copyfile(const char *from, const char *to, struct nsinfo *nsi) | ||
237 | { | ||
238 | int err = -1; | ||
239 | char *line = NULL; | ||
240 | size_t n; | ||
241 | FILE *from_fp, *to_fp; | ||
242 | struct nscookie nsc; | ||
243 | |||
244 | nsinfo__mountns_enter(nsi, &nsc); | ||
245 | from_fp = fopen(from, "r"); | ||
246 | nsinfo__mountns_exit(&nsc); | ||
247 | if (from_fp == NULL) | ||
248 | goto out; | ||
249 | |||
250 | to_fp = fopen(to, "w"); | ||
251 | if (to_fp == NULL) | ||
252 | goto out_fclose_from; | ||
253 | |||
254 | while (getline(&line, &n, from_fp) > 0) | ||
255 | if (fputs(line, to_fp) == EOF) | ||
256 | goto out_fclose_to; | ||
257 | err = 0; | ||
258 | out_fclose_to: | ||
259 | fclose(to_fp); | ||
260 | free(line); | ||
261 | out_fclose_from: | ||
262 | fclose(from_fp); | ||
263 | out: | ||
264 | return err; | ||
265 | } | ||
266 | |||
267 | int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) | ||
268 | { | ||
269 | void *ptr; | ||
270 | loff_t pgoff; | ||
271 | |||
272 | pgoff = off_in & ~(page_size - 1); | ||
273 | off_in -= pgoff; | ||
274 | |||
275 | ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff); | ||
276 | if (ptr == MAP_FAILED) | ||
277 | return -1; | ||
278 | |||
279 | while (size) { | ||
280 | ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out); | ||
281 | if (ret < 0 && errno == EINTR) | ||
282 | continue; | ||
283 | if (ret <= 0) | ||
284 | break; | ||
285 | |||
286 | size -= ret; | ||
287 | off_in += ret; | ||
288 | off_out += ret; | ||
289 | } | ||
290 | munmap(ptr, off_in + size); | ||
291 | |||
292 | return size ? -1 : 0; | ||
293 | } | ||
294 | |||
295 | static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, | ||
296 | struct nsinfo *nsi) | ||
297 | { | ||
298 | int fromfd, tofd; | ||
299 | struct stat st; | ||
300 | int err; | ||
301 | char *tmp = NULL, *ptr = NULL; | ||
302 | struct nscookie nsc; | ||
303 | |||
304 | nsinfo__mountns_enter(nsi, &nsc); | ||
305 | err = stat(from, &st); | ||
306 | nsinfo__mountns_exit(&nsc); | ||
307 | if (err) | ||
308 | goto out; | ||
309 | err = -1; | ||
310 | |||
311 | /* extra 'x' at the end is to reserve space for '.' */ | ||
312 | if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) { | ||
313 | tmp = NULL; | ||
314 | goto out; | ||
315 | } | ||
316 | ptr = strrchr(tmp, '/'); | ||
317 | if (!ptr) | ||
318 | goto out; | ||
319 | ptr = memmove(ptr + 1, ptr, strlen(ptr) - 1); | ||
320 | *ptr = '.'; | ||
321 | |||
322 | tofd = mkstemp(tmp); | ||
323 | if (tofd < 0) | ||
324 | goto out; | ||
325 | |||
326 | if (fchmod(tofd, mode)) | ||
327 | goto out_close_to; | ||
328 | |||
329 | if (st.st_size == 0) { /* /proc? do it slowly... */ | ||
330 | err = slow_copyfile(from, tmp, nsi); | ||
331 | goto out_close_to; | ||
332 | } | ||
333 | |||
334 | nsinfo__mountns_enter(nsi, &nsc); | ||
335 | fromfd = open(from, O_RDONLY); | ||
336 | nsinfo__mountns_exit(&nsc); | ||
337 | if (fromfd < 0) | ||
338 | goto out_close_to; | ||
339 | |||
340 | err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size); | ||
341 | |||
342 | close(fromfd); | ||
343 | out_close_to: | ||
344 | close(tofd); | ||
345 | if (!err) | ||
346 | err = link(tmp, to); | ||
347 | unlink(tmp); | ||
348 | out: | ||
349 | free(tmp); | ||
350 | return err; | ||
351 | } | ||
352 | |||
353 | int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi) | ||
354 | { | ||
355 | return copyfile_mode_ns(from, to, 0755, nsi); | ||
356 | } | ||
357 | |||
358 | int copyfile_mode(const char *from, const char *to, mode_t mode) | ||
359 | { | ||
360 | return copyfile_mode_ns(from, to, mode, NULL); | ||
361 | } | ||
362 | |||
363 | int copyfile(const char *from, const char *to) | ||
364 | { | ||
365 | return copyfile_mode(from, to, 0755); | ||
366 | } | ||
367 | |||
368 | size_t hex_width(u64 v) | 233 | size_t hex_width(u64 v) |
369 | { | 234 | { |
370 | size_t n = 1; | 235 | size_t n = 1; |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index b78b73e5bb32..9969b8b46f7c 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -17,7 +17,6 @@ void usage(const char *err) __noreturn; | |||
17 | void die(const char *err, ...) __noreturn __printf(1, 2); | 17 | void die(const char *err, ...) __noreturn __printf(1, 2); |
18 | 18 | ||
19 | struct dirent; | 19 | struct dirent; |
20 | struct nsinfo; | ||
21 | struct strlist; | 20 | struct strlist; |
22 | 21 | ||
23 | int mkdir_p(char *path, mode_t mode); | 22 | int mkdir_p(char *path, mode_t mode); |
@@ -25,10 +24,6 @@ int rm_rf(const char *path); | |||
25 | int rm_rf_perf_data(const char *path); | 24 | int rm_rf_perf_data(const char *path); |
26 | struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *)); | 25 | struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *)); |
27 | bool lsdir_no_dot_filter(const char *name, struct dirent *d); | 26 | bool lsdir_no_dot_filter(const char *name, struct dirent *d); |
28 | int copyfile(const char *from, const char *to); | ||
29 | int copyfile_mode(const char *from, const char *to, mode_t mode); | ||
30 | int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi); | ||
31 | int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size); | ||
32 | 27 | ||
33 | size_t hex_width(u64 v); | 28 | size_t hex_width(u64 v); |
34 | 29 | ||