summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2019-09-24 14:14:12 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-09-25 08:51:49 -0400
commit32ff3fec07b6d8e6c5cc2342f6cbbdcb224d484c (patch)
tree7b4ecd5ec18e1c0c07f74fb3b6486c66f24f2d5e
parent80ab2987a016f774201d4f3509118047f9d58175 (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/Build1
-rw-r--r--tools/perf/util/build-id.c3
-rw-r--r--tools/perf/util/copyfile.c144
-rw-r--r--tools/perf/util/copyfile.h16
-rw-r--r--tools/perf/util/symbol-elf.c2
-rw-r--r--tools/perf/util/util.c135
-rw-r--r--tools/perf/util/util.h5
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
3perf-y += build-id.o 3perf-y += build-id.o
4perf-y += cacheline.o 4perf-y += cacheline.o
5perf-y += config.o 5perf-y += config.o
6perf-y += copyfile.o
6perf-y += ctype.o 7perf-y += ctype.o
7perf-y += db-export.o 8perf-y += db-export.o
8perf-y += env.o 9perf-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
14static 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;
36out_fclose_to:
37 fclose(to_fp);
38 free(line);
39out_fclose_from:
40 fclose(from_fp);
41out:
42 return err;
43}
44
45int 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
73static 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);
121out_close_to:
122 close(tofd);
123 if (!err)
124 err = link(tmp, to);
125 unlink(tmp);
126out:
127 free(tmp);
128 return err;
129}
130
131int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi)
132{
133 return copyfile_mode_ns(from, to, 0755, nsi);
134}
135
136int copyfile_mode(const char *from, const char *to, mode_t mode)
137{
138 return copyfile_mode_ns(from, to, mode, NULL);
139}
140
141int 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
9struct nsinfo;
10
11int copyfile(const char *from, const char *to);
12int copyfile_mode(const char *from, const char *to, mode_t mode);
13int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi);
14int 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
236static 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;
258out_fclose_to:
259 fclose(to_fp);
260 free(line);
261out_fclose_from:
262 fclose(from_fp);
263out:
264 return err;
265}
266
267int 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
295static 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);
343out_close_to:
344 close(tofd);
345 if (!err)
346 err = link(tmp, to);
347 unlink(tmp);
348out:
349 free(tmp);
350 return err;
351}
352
353int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi)
354{
355 return copyfile_mode_ns(from, to, 0755, nsi);
356}
357
358int copyfile_mode(const char *from, const char *to, mode_t mode)
359{
360 return copyfile_mode_ns(from, to, mode, NULL);
361}
362
363int copyfile(const char *from, const char *to)
364{
365 return copyfile_mode(from, to, 0755);
366}
367
368size_t hex_width(u64 v) 233size_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;
17void die(const char *err, ...) __noreturn __printf(1, 2); 17void die(const char *err, ...) __noreturn __printf(1, 2);
18 18
19struct dirent; 19struct dirent;
20struct nsinfo;
21struct strlist; 20struct strlist;
22 21
23int mkdir_p(char *path, mode_t mode); 22int mkdir_p(char *path, mode_t mode);
@@ -25,10 +24,6 @@ int rm_rf(const char *path);
25int rm_rf_perf_data(const char *path); 24int rm_rf_perf_data(const char *path);
26struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *)); 25struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *));
27bool lsdir_no_dot_filter(const char *name, struct dirent *d); 26bool lsdir_no_dot_filter(const char *name, struct dirent *d);
28int copyfile(const char *from, const char *to);
29int copyfile_mode(const char *from, const char *to, mode_t mode);
30int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi);
31int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size);
32 27
33size_t hex_width(u64 v); 28size_t hex_width(u64 v);
34 29