[<prev] [next>] [day] [month] [year] [list]
Message-ID: <1f7127f4-6f32-8b4f-5bc2-3f35a337bc1a@huawei.com>
Date: Thu, 23 Dec 2021 09:58:15 +0800
From: yaowenbin <yaowenbin1@...wei.com>
To: <peterz@...radead.org>, <mingo@...hat.com>, <acme@...nel.org>,
<mark.rutland@....com>, <alexander.shishkin@...ux.intel.com>,
<jolsa@...hat.com>, <namhyung@...nel.org>,
<thunder.leizhen@...wei.com>, <rickyman7@...il.com>,
<ak@...ux.intel.com>, <adrian.hunter@...el.com>,
<yaowenbin1@...wei.com>, <linux-perf-users@...r.kernel.org>,
<linux-kernel@...r.kernel.org>
CC: <hewenliang4@...wei.com>, <wuxu.wu@...wei.com>
Subject: [PATCH] perf record: Add O_EXCL flag for opening perf.data file
When the following command is executed, a coredump file is generated.
$ perf record -e cpu-clock sleep 3 & perf record -e cpu-clock sleep 3 &
[1] 213456
[2] 213457
[ perf record: Woken up 1 times to write data ]
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.012 MB perf.data (4 samples) ]
[1]- Bus error (core dumped) perf record -e cpu-clock sleep 3
[2]+ Done perf record -e cpu-clock sleep 3
It is a problem of concurrent access of perf.data file. When several
processes execute "perf record" command in the same directory
concurrently, they may open the same perf.data file, and write
the same file, causing data confusion. It may cause coredump when
reading the file. Then add O_EXCL flag to ensure that there is only
one process operating the perf.data file in the same directory concurrently.
After adding O_EXCL flag, the open operation will fail if there is
a perf.data file existing in the same directory, so also rename the
perf.data file to perf.data.old even if the size of perf.data is zero.
Signed-off-by: yaowenbin <yaowenbin1@...wei.com>
---
tools/perf/util/data.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index f5d260b1df4d..92cf0aa3ed83 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -201,7 +201,7 @@ static int check_backup(struct perf_data *data)
if (perf_data__is_read(data))
return 0;
- if (!stat(data->path, &st) && st.st_size) {
+ if (!stat(data->path, &st)) {
char oldname[PATH_MAX];
int ret;
@@ -285,7 +285,7 @@ static int open_file_write(struct perf_data *data)
int fd;
char sbuf[STRERR_BUFSIZE];
- fd = open(data->file.path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC,
+ fd = open(data->file.path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC|O_EXCL,
S_IRUSR|S_IWUSR);
if (fd < 0)
--
2.27.0
Powered by blists - more mailing lists