bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

broken pipe from func-output by changing network settings?


From: L A Walsh
Subject: broken pipe from func-output by changing network settings?
Date: Tue, 17 Oct 2017 03:28:46 -0700
User-agent: Thunderbird

I was trying a different network setting in ethtool regarding
the receive wait time before it processes an incoming data packet.

It was set to 1 microsecond
(ethtool -c shows it as rx-usecs: 1), and I wanted to try 0 microseconds
to see what effect it had on receiving a file.  Presumably one might
want it to be 1 if several packets might be received in less than 1
microsecond, so they can be coalesced into 1 packet to be sent to
the OS from the adapter.
I could explain whys and wherefores, but in order not to put anyone
to sleep, I have a script I use for sanity checks on my network-file
send & receive to/from a Win7 client <->linux(samba).

I run the test using cygwin, and use /dev/zero and /dev/null --
creating those files in my home directory on each platform.

That way I can copy from /dev/zero on one platform to /dev/null on the other
or vice-versa to get timings of file transfer speed, APART from
file-io delays of going through the file system.

In going to '0', I'm now getting:
/h> bin/iotest
Using bs=4.0M, count=4, iosize=16.0M
R:bin/iotest: line 112: /dev/fd/62: No such file or directory
cat: write error: Broken pipe
W:bin/iotest: line 112: /dev/fd/62: No such file or directory
/h> cat: write error: Broken pipe

The code segment in question is reading from a file descriptor
via "< <(xxx)"

Specifically in the readarray in the 2nd function:
-------
sub dd_need_io  {
   local if="$1" of="$2"; shift 2
   nice --19 $Dd if="$if" of="$of" bs="$BS" count="$count" iflag=fullblock\
                 conv=nocreat "$@"
}

sub dd {
   local if="$1" of="$2" ;shift 2
   array out=()
   my ignore_RE='^[^ \t]+ records\ (in|out)$'
   readarray out < <(  dd_need_io "$if" "$of" "$@" |& { int s=$?
if ((s)); then echo >&2 "stat:$s"; else cat; fi ; }
                     )
   printf "%s\n" "${out[@]}"
   return 0
}
-------


So my question is -- how can the pipe disappear so fast
that my "readarray out" results in a broken pipe message.

Shouldn't that be impossible with the code above?

FWIW, the readarray is trying to catch the output from 'dd',
with 's' catching the status of the 'dd' command (as passed
through nice).

But why would changing network settings on an ethernet
node result in pipe errors in bash?

Ideas?

p.s. My main desktop is down, so using a friends' DT for email, so
I may be delayed in responses ...

Thanks!
-linda

#!/bin/bash 
# iotest v0.1 - lawalsh: open usage allowed
# vim=:SetNumberAndWidth

_prgpth="${0:?}"; _prg="${_prgpth##*/}"; _prgdr="${_prgpth%/$_prg}"
[[ -z $_prgdr || $_prg == $_prgdr ]] && $_prgdr="$PWD"
export PATH="$_prgdr:$_prgdr/lib:$PATH"
shopt -s expand_aliases extglob sourcepath ; set -o pipefail

#include stdalias

Dd=$(type -P dd)

[[ $Dd ]] || { echo "Cannot find dd.  Cannot proceed.";  exit 1; }

alias   my=declare sub=function int='my -i' array='my -a' 
alias map='my -A' intConst='int -x' string=my

# 1 num = block size
# num-num = range of block sizes to test; w/increment = "2x", so
# 4M-16M tests 4M, 8M, 16M
# 4M-12M test 4M, 8M, 12M
# count adjusted to xfer 4G, rounding up
#----

#all xfers are using 'devices' (/dev/zero for source, /dev/null for target)
# remote filenames "zero" and "null" should be setup to be remote devices

intConst K=1024 M=K*K G=M*K T=G*K

##
# Defaults for BS count and IOSIZE
##
int BS=$[4*M] 
int count=4
int IOSIZE=$count*$BS


#       desuffix        arg1 [arg2]
#       desuffix        arg1 - num + suffix -> convert to int
#                                               arg2 - optional buff name (else 
print to stdout)
#                                               return 0 if no error
sub desuffix {                                          #convert num+Suff => 
int store in optional Buff
        my str="${1:?}" ; shift
        my bufnam=""; (($#)) && bufnam=$1
        if [[ $str =~ ^([0-9]+)([KMGT])$ ]]; then 
                int num=${BASH_REMATCH[1]}*${BASH_REMATCH[2]}
                ((num)) || return 1
                if [[ $bufnam ]] ; then printf -v $bufnam "%d" "$num"
                else printf "%d" "$num" ; fi
        else 
                return $p 
        fi
}


sub hdisp {
        my parm=${1:?}
        if [[ ! $parm =~ ^[0-9]+$ ]]; then echo >&2 "hdisp: parm1 is not num: 
\"$parm\""; fi
        int num=${1:?}; shift
        export PERL5OPT="$PERL5OPT -I/h/bin/lib"
        my buf="$(perl -e 'use Hout; use P; P "%s", human($ARGV[0]);' "$num")"
        #printf "hdisp-buf=%s\n" "$buf"
        string bufnam=""; (($#)) && bufnam=$1
        if [[ $bufnam ]] ; then printf -v $bufnam "%s" "$buf"
        else printf "%s" "$buf" ; fi
}

map args=([b]=setblocksize [i]=iosize )

sub setblocksize { BS=$1 ; }

sub iosize { IOSIZE=$1 ; }

sub check_params {
        int num=0
        while (($#)) ; do
                my arg=$1 ; shift
                if [[ ${arg:0:1} == - ]]; then arg=${arg:1}; fi
                my switch=${args["$arg"]:-""}
                int iswitch=0
                if [[ ${switch:-""} ]]; then
                        my val=$1; shift
                        my nval=""
                        int ival=0
                        desuffix "$val" nval
                        if [[ $nval ]]; then ival=0+nval; fi
                        $switch $ival
                fi
        done
        count=IOSIZE/BS
}

(($#)) && check_params "$@"

#string testdir=/h/iotest.points
string testdir=/h

array reada=($testdir/zero /dev/null )
array writea=(/dev/zero $testdir/null oflag=direct conv=nocreat,notrunc)

sub dd_need_io  {
        local if="$1" of="$2"; shift 2
        nice --19 $Dd if="$if" of="$of" bs="$BS" count="$count" iflag=fullblock\
                        conv=nocreat "$@"
}

sub dd {
        local if="$1" of="$2" ;shift 2
        array out=()
        my ignore_RE='^[^ \t]+ records\ (in|out)$'
        readarray out < <(      dd_need_io "$if" "$of" "$@" |& { int s=$?
                                                                                
                if ((s)); then echo >&2 "stat:$s"; else cat; fi ; }
                                                                                
)
        printf "%s\n" "${out[@]}"
        return 0
}
        
function dd_format { 
        my bytes btxt pnum1 suffp1 pnum2 suffp2 copt time rest
        while read bytes btxt pnum1 suffp1 pnum2 suffp2 copt time rest; do
                if ! [[ $time =~ ^[0-9] ]]; then
                        copt=$pnum2; time=$suffp2;
                fi
                [[ $btxt == records ]] && continue
                [[ $bytes && $time ]] || continue
                my sizeb="" rateb=""
                my bps="$(echo -E "$bytes/$time" | bc)"
                hdisp "$bytes" sizeb
                hdisp "$bps" rateb
                my fmt="%d bytes (%sB) copied, %s s, %sB/s\n"
                printf "$fmt" "$bytes" "$sizeb" "$time" "$rateb"
        done 
}

sub onecycle {
        echo -n "R:"; { dd "${reada[@]}"|| exit $?; } | dd_format
        sync;sleep .1;sync
        echo -n "W:";   { dd "${writea[@]}" || exit $?; } | dd_format 
}

my bsbuf="" ios_buf=""

hdisp "$BS" bsbuf
hdisp "$IOSIZE" ios_buf

printf "Using bs=%s, count=%s, iosize=%s\n" "$bsbuf" "$count" "$ios_buf"


onecycle

reply via email to

[Prev in Thread] Current Thread [Next in Thread]