diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2011-03-12 18:58:55 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2011-03-12 18:58:55 +0000 |
commit | 30c1ecbeb90c0d739a2f8dd74d15e05b79aba36e (patch) | |
tree | 659e6830f5f0fffaf78f2fca9ae82d20ca92fceb /regress | |
parent | aecea21552924c16781358d7983dc098272afbf9 (diff) |
Add more regression tests for socket splicing. These find the
kernel bugs that have slipped through.
Diffstat (limited to 'regress')
-rw-r--r-- | regress/sys/kern/splice/args-max-time.pl | 23 | ||||
-rw-r--r-- | regress/sys/kern/splice/args-relay-read-blocking.pl | 17 | ||||
-rw-r--r-- | regress/sys/kern/splice/args-relay-read-forked.pl | 36 | ||||
-rw-r--r-- | regress/sys/kern/splice/args-relay-write-forked.pl | 38 | ||||
-rw-r--r-- | regress/sys/kern/splice/funcs.pl | 28 |
5 files changed, 135 insertions, 7 deletions
diff --git a/regress/sys/kern/splice/args-max-time.pl b/regress/sys/kern/splice/args-max-time.pl new file mode 100644 index 00000000000..438964ecd3f --- /dev/null +++ b/regress/sys/kern/splice/args-max-time.pl @@ -0,0 +1,23 @@ +# test immediate data transfer after maximum data length + +use strict; +use warnings; + +our %args = ( + client => { + func => sub { $| = 1; errignore(@_); write_char(@_); sleep(6); }, + nocheck => 1, + }, + relay => { + func => sub { relay(@_); sleep(5); }, + max => 63, + }, + server => { + func => sub { alarm(4); read_char(@_); }, + max => 63, + }, + len => 63, + md5 => "4a3c3783fc56943715c53e435973b2ee", +); + +1; diff --git a/regress/sys/kern/splice/args-relay-read-blocking.pl b/regress/sys/kern/splice/args-relay-read-blocking.pl new file mode 100644 index 00000000000..0ecc4c12cf7 --- /dev/null +++ b/regress/sys/kern/splice/args-relay-read-blocking.pl @@ -0,0 +1,17 @@ +# test waiting for splice finish with blocking read + +use strict; +use warnings; + +our %args = ( + client => { + len => 2**17, + }, + relay => { + readblocking => 1, + }, + len => 131072, + md5 => "31e5ad3d0d2aeb1ad8aaa847dfa665c2", +); + +1; diff --git a/regress/sys/kern/splice/args-relay-read-forked.pl b/regress/sys/kern/splice/args-relay-read-forked.pl new file mode 100644 index 00000000000..36ac91de1e4 --- /dev/null +++ b/regress/sys/kern/splice/args-relay-read-forked.pl @@ -0,0 +1,36 @@ +# test concurrent read and splice + +use strict; +use warnings; + +our %args = ( + client => { + len => 2**20, + }, + relay => { + nonblocking => 1, + func => sub { + defined(my $pid = fork()) + or die "relay func: fork failed: $!"; + if ($pid) { + relay(@_); + return; + } + my $n; + do { + $n = sysread(STDIN, my $buf, 10); + } while (!defined($n) || $n); + POSIX::_exit(0); + }, + }, + server => { + func => sub { sleep 2; read_char(@_); }, + }, + # As sysread() may extract data from the socket before splicing starts, + # the spliced content length is not reliable. Disable the checks. + nocheck => 1, + len => 1048576, + md5 => '6649bbec13f3d7efaedf01c0cfa54f88', +); + +1; diff --git a/regress/sys/kern/splice/args-relay-write-forked.pl b/regress/sys/kern/splice/args-relay-write-forked.pl new file mode 100644 index 00000000000..3717e112d8b --- /dev/null +++ b/regress/sys/kern/splice/args-relay-write-forked.pl @@ -0,0 +1,38 @@ +# test concurrent write and splice + +use strict; +use warnings; +use Time::HiRes 'sleep'; + +our %args = ( + client => { + len => 2**20, + }, + relay => { + func => sub { + defined(my $pid = fork()) + or die "relay func: fork failed: $!"; + if ($pid) { + relay(@_); + kill 15, $pid; + return; + } + my $n; + do { + $n = syswrite(STDOUT, "\n foo bar\n"); + sleep .1; + } while (defined($n)); + POSIX::_exit(0); + }, + }, + server => { + func => sub { sleep 2; read_char(@_); }, + }, + # As syswrite() adds data to the socket, the content length is not + # correct. Disable the checks. + nocheck => 1, + len => 1048576, + md5 => '6649bbec13f3d7efaedf01c0cfa54f88', +); + +1; diff --git a/regress/sys/kern/splice/funcs.pl b/regress/sys/kern/splice/funcs.pl index 8973e864af0..973b5db8e6e 100644 --- a/regress/sys/kern/splice/funcs.pl +++ b/regress/sys/kern/splice/funcs.pl @@ -1,6 +1,6 @@ -# $OpenBSD: funcs.pl,v 1.2 2011/02/14 22:36:15 bluhm Exp $ +# $OpenBSD: funcs.pl,v 1.3 2011/03/12 18:58:54 bluhm Exp $ -# Copyright (c) 2010 Alexander Bluhm <bluhm@openbsd.org> +# Copyright (c) 2010,2011 Alexander Bluhm <bluhm@openbsd.org> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -194,10 +194,19 @@ sub relay_splice { setsockopt(STDIN, SOL_SOCKET, SO_SPLICE, $sosplice) or die ref($self), " splice stdin to stdout failed: $!"; - my $rin = ''; - vec($rin, fileno(STDIN), 1) = 1; - select($rin, undef, undef, undef) - or die ref($self), " select failed: $!"; + if ($self->{readblocking}) { + # block by reading from the source socket + defined(my $read = sysread(STDIN, my $buf, 2**16)) + or die ref($self), " read blocking failed: $!"; + $read > 0 and die ref($self), + " read blocking has data: $read"; + print STDERR "Read\n"; + } else { + my $rin = ''; + vec($rin, fileno(STDIN), 1) = 1; + select($rin, undef, undef, undef) + or die ref($self), " select failed: $!"; + } my $error = getsockopt(STDIN, SOL_SOCKET, SO_ERROR) or die ref($self), " get error from stdin failed: $!"; @@ -221,7 +230,7 @@ sub relay_splice { } elsif ($max && $max > $len && $splicelen) { die ref($self), " max $max greater than len $len"; } else { - defined(my $read = sysread(STDIN, my $buf, 2**16)) + defined(my $read = sysread(STDIN, my $buf, 2**16)) or die ref($self), " sysread stdin failed: $!"; $read > 0 and die ref($self), " sysread stdin has data: $read"; @@ -297,6 +306,7 @@ sub shutout { sub read_char { my $self = shift; + my $max = shift // $self->{max}; my $ctx = Digest::MD5->new(); my $len = 0; @@ -304,6 +314,10 @@ sub read_char { $len += length($_); $ctx->add($_); print STDERR "."; + if ($max && $len >= $max) { + print STDERR "\nMax"; + last; + } } print STDERR "\n"; |