yahns Ruby server user/dev discussion
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: [PATCH 2/2] wbuf: avoid corrupted large responses with zero-copy sendfile
  2014-07-16 19:57  5% ` [PATCH 2/2] wbuf: avoid corrupted large responses with zero-copy sendfile Eric Wong
@ 2015-03-07 21:36  7%   ` Eric Wong
  0 siblings, 0 replies; 3+ results
From: Eric Wong @ 2015-03-07 21:36 UTC (permalink / raw)
  To: yahns-public

Eric Wong <e@80x24.org> wrote:
> This bug is noticeable on a amd64 FreeBSD 9.2 VM, and possible under
> Linux, too.  This happens as a zero-copy sendfile implementation means
> pages queued for transmission by the sendfile system call should not be
> modified at any point after the sendfile syscall is made.

Btw, this gotcha is now noted in the Linux sendfile(2) manpage:

http://git.kernel.org/cgit/docs/man-pages/man-pages.git/commit/man2/sendfile.2?id=7b6a3299776b5c1c4f169a591434a855d50c68b4

^ permalink raw reply	[relevance 7%]

* [ANN] yahns 1.3.1 - fix large response corruption
@ 2014-07-16 20:13  5% Eric Wong
  0 siblings, 0 replies; 3+ results
From: Eric Wong @ 2014-07-16 20:13 UTC (permalink / raw)
  To: yahns-public

This release contains a major bug fix noticeable on FreeBSD VMs, but
should affect Linux systems making large responses which require
output buffering, too.

- test_server: avoid multiple workers for dead parent check
- wbuf: avoid corrupted large responses with zero-copy sendfile

* git clone git://yhbt.net/yahns
* http://yahns.yhbt.net/README
* http://yahns.yhbt.net/NEWS.atom.xml
* yahns-public@yhbt.net

^ permalink raw reply	[relevance 5%]

* [PATCH 2/2] wbuf: avoid corrupted large responses with zero-copy sendfile
  @ 2014-07-16 19:57  5% ` Eric Wong
  2015-03-07 21:36  7%   ` Eric Wong
  0 siblings, 1 reply; 3+ results
From: Eric Wong @ 2014-07-16 19:57 UTC (permalink / raw)
  To: yahns-public; +Cc: e, Eric Wong

From: Eric Wong <e+fbsd@80x24.org>

This bug is noticeable on a amd64 FreeBSD 9.2 VM, and possible under
Linux, too.  This happens as a zero-copy sendfile implementation means
pages queued for transmission by the sendfile system call should not be
modified at any point after the sendfile syscall is made.

To prevent modification, we replace the temporary file with a new one.
This has a similar effect as truncate and can still prevent a dirty
flush in cases when a client consumes the response fast enough.

This reverts the misguided ade89b5142bedbcf07f38aa062bfdbfcb8bc48d3
commit ("wbuf: hack to avoid response corruption on FreeBSD")

Note: this bug was finally fixed because I finally noticed this flaw
in a different (non-Ruby, non-HTTP) server of mine.
---
 lib/yahns/wbuf.rb | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/lib/yahns/wbuf.rb b/lib/yahns/wbuf.rb
index 21bccce..991557e 100644
--- a/lib/yahns/wbuf.rb
+++ b/lib/yahns/wbuf.rb
@@ -30,16 +30,9 @@ require_relative 'wbuf_common'
 class Yahns::Wbuf # :nodoc:
   include Yahns::WbufCommon
 
-  # TODO: Figure out why this hack is needed to pass output buffering tests.
-  # It could be a bug in our code, Ruby, the sendfile gem, or FreeBSD itself.
-  # Tested on FreeBSD fbsd 9.2-RELEASE FreeBSD 9.2-RELEASE #0 r255898
-  # We are able to use bypass mode on Linux to reduce buffering in some
-  # cases.  Without bypass mode, we must always finish writing the entire
-  # response completely before sending more data to the client.
-  bypass_ok = RUBY_PLATFORM =~ /linux/
-
   def initialize(body, persist, tmpdir)
     @tmpio = Yahns::TmpIO.new(tmpdir)
+    @tmpdir = tmpdir
     @sf_offset = @sf_count = 0
     @wbuf_persist = persist # whether or not we keep the connection alive
     @body = body
@@ -71,16 +64,12 @@ class Yahns::Wbuf # :nodoc:
 
     # we're all caught up, try to prevent dirty data from getting flushed
     # to disk if we can help it.
-    @tmpio.truncate(@sf_offset = 0)
-    @tmpio.rewind
+    @tmpio.close
+    @sf_offset = 0
+    @tmpio = Yahns::TmpIO.new(@tmpdir)
     @bypass = true
     nil
-  end if bypass_ok
-
-  def wbuf_write(client, buf)
-    @sf_count += @tmpio.write(buf)
-    :wait_writable
-  end unless bypass_ok
+  end
 
   # called by last wbuf_flush
   def wbuf_close(client)
-- 
EW


^ permalink raw reply related	[relevance 5%]

Results 1-3 of 3 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2014-07-16 19:57     [PATCH 0/2] FreeBSD-related fixes (affects Linux users, too) Eric Wong
2014-07-16 19:57  5% ` [PATCH 2/2] wbuf: avoid corrupted large responses with zero-copy sendfile Eric Wong
2015-03-07 21:36  7%   ` Eric Wong
2014-07-16 20:13  5% [ANN] yahns 1.3.1 - fix large response corruption Eric Wong

Code repositories for project(s) associated with this public inbox

	https://yhbt.net/yahns.git/

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 read-only IMAP folder(s) and NNTP newsgroup(s).