Commit 040f9915 authored by Wang Nan's avatar Wang Nan Committed by Arnaldo Carvalho de Melo
Browse files

perf data: Add perf_data_file__switch() helper



perf_data_file__switch() closes current output file, renames it, then
open a new one to continue recording. It will be used by 'perf record'
to split output into multiple perf.data files.

Signed-off-by: default avatarWang Nan <wangnan0@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1460535673-159866-3-git-send-email-wangnan0@huawei.com


Signed-off-by: default avatarHe Kuang <hekuang@huawei.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent b26dc730
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -136,3 +136,44 @@ ssize_t perf_data_file__write(struct perf_data_file *file,
{
	return writen(file->fd, buf, size);
}

int perf_data_file__switch(struct perf_data_file *file,
			   const char *postfix,
			   size_t pos, bool at_exit)
{
	char *new_filepath;
	int ret;

	if (check_pipe(file))
		return -EINVAL;
	if (perf_data_file__is_read(file))
		return -EINVAL;

	if (asprintf(&new_filepath, "%s.%s", file->path, postfix) < 0)
		return -ENOMEM;

	/*
	 * Only fire a warning, don't return error, continue fill
	 * original file.
	 */
	if (rename(file->path, new_filepath))
		pr_warning("Failed to rename %s to %s\n", file->path, new_filepath);

	if (!at_exit) {
		close(file->fd);
		ret = perf_data_file__open(file);
		if (ret < 0)
			goto out;

		if (lseek(file->fd, pos, SEEK_SET) == (off_t)-1) {
			ret = -errno;
			pr_debug("Failed to lseek to %zu: %s",
				 pos, strerror(errno));
			goto out;
		}
	}
	ret = file->fd;
out:
	free(new_filepath);
	return ret;
}
+10 −1
Original line number Diff line number Diff line
@@ -46,5 +46,14 @@ int perf_data_file__open(struct perf_data_file *file);
void perf_data_file__close(struct perf_data_file *file);
ssize_t perf_data_file__write(struct perf_data_file *file,
			      void *buf, size_t size);

/*
 * If at_exit is set, only rename current perf.data to
 * perf.data.<postfix>, continue write on original file.
 * Set at_exit when flushing the last output.
 *
 * Return value is fd of new output.
 */
int perf_data_file__switch(struct perf_data_file *file,
			   const char *postfix,
			   size_t pos, bool at_exit);
#endif /* __PERF_DATA_H */