linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Yordan Karadzhov <y.karadz@gmail.com>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: linux-trace-devel@vger.kernel.org
Subject: Re: [PATCH v3] libtracefs: Add APIs for data streaming
Date: Fri, 25 Jun 2021 16:57:58 +0300	[thread overview]
Message-ID: <e2ab5710-95f9-f510-5249-3291c68b9ae5@gmail.com> (raw)
In-Reply-To: <20210625094624.6da9a90f@oasis.local.home>



On 25.06.21 г. 16:46, Steven Rostedt wrote:
> On Fri, 25 Jun 2021 16:17:14 +0300
> Yordan Karadzhov <y.karadz@gmail.com> wrote:
> 
>> On 24.06.21 г. 19:45, Steven Rostedt wrote:
>>> On Thu, 24 Jun 2021 17:51:01 +0300
>>> "Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:
>>>    
>>>> The new APIs can be used to dump the content of "trace_pipe" into a
>>>> file or directly to "stdout". The "splice" system call is used to
>>>> moves the data without copying. The new functionality is essentially
>>>> identical to what 'trace-cmd show -p' does.
>>>>
>>>> Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
>>>>   
>>>
>>> So I did some investigations here, and found that splice() is not
>>> guaranteed to work on a terminal output.
>>>
>>> To overcome this, I decided to have the print create another pipe, and
>>> pass that to the stream code. The if something was read, it would read
>>> the pipe.
>>>
>>> It required changing the return of the functions to return the amount
>>> transferred, so that I can differentiate between "EOF" with nothing
>>> read, and something read. Because I couldn't get the pipe to not block
>>> on read if there was no content in it. :-/
>>>
>>> Anyway, I submitted a v4 with the changes I made, and it appears to
>>> work. I haven't tested it that much, so it may still have bugs.
>>>    
>>
>> Hi Steve,
>>
>> I tested v4 of the patch that you submitted and it doesn't work correct in my use case. Also it seems greatly
>> over-complicated to me. Note that when you call tracefs_trace_pipe_stream() inside a loop you will keep opening and
>> closing the "trace_pipe" and the pipe over and over again.
> 
> Good point. I could update it to pull out the main work of the splice
> logic and have both functions use that, and not have one call the other.
> 
> What didn't work with your use case?
> 
>>
>> See the example code below. Is this what you are aiming? Also is this guaranteed to always work?
> 
> Similar but I'll comment below. Note, the real issue I had in testing
> my code was blocking. The read on the pipe would block on EOF even with
> a NONBLOCK flag :-/ Which is not what I wanted, and to fix that, it
> made the code a bit more complex.
> 
>>
>> Thanks!
>> Yordan
>>
>>
>> #define _GNU_SOURCE
>> #include <fcntl.h>
>> #include <unistd.h>
>> #include <signal.h>
>> #include <stdbool.h>
>> #include <stdio.h>
>> #include <errno.h>
>>
>> volatile bool keep_going = true;
>>
>> static void finish(int sig)
>> {
>> 	keep_going = false;
>> }
>>
>> int main(int argc, char **argv)
>> {
>> 	int splice_flags = SPLICE_F_MORE | SPLICE_F_MOVE;
>> 	int brass1[2], brass2[2], fd, ret;
>> 	char buf[BUFSIZ];
>>
>> 	signal(SIGINT, finish);
>>
>> 	fd = open(argv[1], O_RDONLY);
>> 	if (fd < 0) {
>> 		perror("open");
>> 		return 1;
>> 	}
>>
>> 	if (pipe(brass1) < 0){
>> 		perror("pipe A");
>> 		return 1;
>> 	}
>>
>> 	if (pipe(brass2) < 0){
>> 		perror("pipe B");
>> 		return 1;
>> 	}
>>
>> 	errno = 0;
>> 	while (keep_going) {
>> 		ret = splice(fd, NULL,
>> 			     brass1[1], NULL,
>> 			     BUFSIZ, splice_flags);
> 
> The above can block, and if it does, and you hit "ctrl-C" it will
> return with ret < 0 and have errno set to EINTR.
> 
>> 		if (ret < 0) {
> 
> With a Ctrl-C, this would error.

Yes, Isn't this what we want. We want to stop the loop.

Thanks!
Y.

> 
>> 			perror("splice A");
>> 			return 1;
>> 		}
>> 		ret = splice(brass1[0], NULL,
>> 			     brass2[1], NULL,
>> 			     BUFSIZ, splice_flags);
>> 		if (ret < 0) {
>> 			perror("splice B");
>> 			return 1;
>> 		}
>>
>> 		ret = read(brass2[0], buf, BUFSIZ);
> 
> Same here, with the blocking issue.
> 
> -- Steve
> 
>> 		if (ret < 0) {
>> 			perror("read");
>> 			return 1;
>> 		}
>>
>> 		ret = write(STDOUT_FILENO, buf, ret);
>> 		if (ret < 0) {
>> 			perror("write");
>> 			return 1;
>> 		}
>> 	}
>>
>> 	close(fd);
>> 	close(brass1[0]);
>> 	close(brass1[1]);
>> 	close(brass2[0]);
>> 	close(brass2[1]);
>>
>> 	return 0;
>> }

      reply	other threads:[~2021-06-25 13:58 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-24 14:51 [PATCH v3] libtracefs: Add APIs for data streaming Yordan Karadzhov (VMware)
2021-06-24 16:45 ` Steven Rostedt
2021-06-25 13:17   ` Yordan Karadzhov
2021-06-25 13:46     ` Steven Rostedt
2021-06-25 13:57       ` Yordan Karadzhov [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e2ab5710-95f9-f510-5249-3291c68b9ae5@gmail.com \
    --to=y.karadz@gmail.com \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).