intermittent stderr

John Dunlap dunlap at apl.washington.edu
Mon Feb 26 05:43:03 EST 2001


The patches below seem to cure the total lack of response,
but there are still "select: Bad file descriptor" messages.
I patched two machines, a fast (500-P3) and a slow(166-P1) and ran this 
script from the slow one.  I started with a clean OpenSSH-2.5.1p1
tar ball.  Both machines are RHL6.2 with all RPM updates except
recent February kernel upgrade.
--John

# cat tst
#!/bin/sh
while [ 1 ]
do
	date
	ssh fasthost ls -l /doesnotexist
done

# sh tst
Sun Feb 25 10:40:00 PST 2001
ls: /doesnotexist: No such file or directory
Sun Feb 25 10:40:04 PST 2001
select: Bad file descriptor
Sun Feb 25 10:40:08 PST 2001
ls: /doesnotexist: No such file or directory
Sun Feb 25 10:40:11 PST 2001
select: Bad file descriptor
Sun Feb 25 10:40:15 PST 2001
ls: select: Bad file descriptor
Sun Feb 25 10:40:18 PST 2001
ls: /doesnotexist: No such file or directory
Sun Feb 25 10:40:22 PST 2001
ls: /doesnotexist: No such file or directory
Sun Feb 25 10:40:25 PST 2001
ls: /doesnotexist: No such file or directory
Sun Feb 25 10:40:29 PST 2001
ls: /doesnotexist: No such file or directory
Sun Feb 25 10:40:33 PST 2001



> 
> On Thu, Feb 22, 2001 at 02:30:43PM -0800, John Dunlap wrote:
> > The command "ssh ls -l /doesnotexist" gives various responses:
> 
> please try this patch.
> 
> after close of stdin/out remaining stderr data is ignored
> in the 'channel' layer of openssh-current.
> 
> 
> Index: nchan.c
> ===================================================================
> RCS file: /home/markus/cvs/ssh/nchan.c,v
> retrieving revision 1.22
> diff -u -r1.22 nchan.c
> --- nchan.c	2001/01/21 19:05:52	1.22
> +++ nchan.c	2001/02/25 16:19:55
> @@ -406,14 +406,40 @@
>  {
>  	debug3("channel %d: chan_delete_if_full_closed2: istate %d ostate %d",
>  	    c->self, c->istate, c->ostate);
> +
>  	if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) {
> -		if (!(c->flags & CHAN_CLOSE_SENT)) {
> -			chan_send_close2(c);
> -		}
> -		if ((c->flags & CHAN_CLOSE_SENT) &&
> -		    (c->flags & CHAN_CLOSE_RCVD)) {
> -			debug("channel %d: full closed2", c->self);
> -			channel_free(c->self);
> +		/*
> +		 * we have to delay the close message if the efd (for stderr)
> +		 * is still active
> +		 */
> +		if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
> +		    buffer_len(&c->extended) > 0)
> +#if 0
> +		    || ((c->extended_usage == CHAN_EXTENDED_READ) &&
> +		    c->efd != -1)
> +#endif
> +		    ) {
> +			debug2("channel %d: active efd: %d len %d type %s",
> +			    c->self, c->efd, buffer_len(&c->extended),
> +			    c->extended_usage==CHAN_EXTENDED_READ ?
> +			       "read": "write");
> +		} else {
> +#if 0
> +			if (c->efd != -1) {
> +				debug("channel %d: delayed close for efd %d",
> +				    c->self, c->efd);
> +				close(c->efd);
> +				c->efd = -1;
> +			}
> +#endif
> +			if (!(c->flags & CHAN_CLOSE_SENT)) {
> +				chan_send_close2(c);
> +			}
> +			if ((c->flags & CHAN_CLOSE_SENT) &&
> +			    (c->flags & CHAN_CLOSE_RCVD)) {
> +				debug("channel %d: full closed2", c->self);
> +				channel_free(c->self);
> +			}
>  		}
>  	}
>  }
> Index: channels.c
> ===================================================================
> RCS file: /home/markus/cvs/ssh/channels.c,v
> retrieving revision 1.92
> diff -u -r1.92 channels.c
> --- channels.c	2001/02/16 13:38:18	1.92
> +++ channels.c	2001/02/25 16:12:59
> @@ -824,7 +824,14 @@
>  			    buffer_len(&c->extended));
>  			debug2("channel %d: written %d to efd %d",
>  			    c->self, len, c->efd);
> -			if (len > 0) {
> +			if (len < 0 && (errno == EINTR || errno == EAGAIN))
> +				return 1;
> +			if (len <= 0) {
> +				debug2("channel %d: closing write-efd %d",
> +				    c->self, c->efd);
> +				close(c->efd);
> +				c->efd = -1;
> +			} else {
>  				buffer_consume(&c->extended, len);
>  				c->local_consumed += len;
>  			}
> @@ -833,13 +840,16 @@
>  			len = read(c->efd, buf, sizeof(buf));
>  			debug2("channel %d: read %d from efd %d",
>  			     c->self, len, c->efd);
> -			if (len == 0) {
> -				debug("channel %d: closing efd %d",
> +			if (len < 0 && (errno == EINTR || errno == EAGAIN))
> +				return 1;
> +			if (len <= 0) {
> +				debug2("channel %d: closing read-efd %d",
>  				    c->self, c->efd);
>  				close(c->efd);
>  				c->efd = -1;
> -			} else if (len > 0)
> +			} else {
>  				buffer_append(&c->extended, buf, len);
> +			}
>  		}
>  	}
>  	return 1;
> @@ -1037,19 +1047,18 @@
>  		} else {
>  			if (c->type != SSH_CHANNEL_OPEN)
>  				continue;
> -			if (c->istate != CHAN_INPUT_OPEN &&
> -			    c->istate != CHAN_INPUT_WAIT_DRAIN)
> -				continue;
>  		}
>  		if (compat20 &&
>  		    (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
> +			/* XXX is this true? */
>  			debug("channel: %d: no data after CLOSE", c->self);
>  			continue;
>  		}
>  
>  		/* Get the amount of buffered data for this channel. */
> -		len = buffer_len(&c->input);
> -		if (len > 0) {
> +		if ((c->istate == CHAN_INPUT_OPEN ||
> +		    c->istate == CHAN_INPUT_WAIT_DRAIN) &&
> +		    (len = buffer_len(&c->input)) > 0) {
>  			/* Send some data for the other side over the secure connection. */
>  			if (compat20) {
>  				if (len > c->remote_window)
> @@ -1089,6 +1098,9 @@
>  		    c->remote_window > 0 &&
>  		    (len = buffer_len(&c->extended)) > 0 &&
>  		    c->extended_usage == CHAN_EXTENDED_READ) {
> +			debug2("channel %d: rwin %d elen %d euse %d",
> +			    c->self, c->remote_window, buffer_len(&c->extended),
> +			    c->extended_usage);
>  			if (len > c->remote_window)
>  				len = c->remote_window;
>  			if (len > c->remote_maxpacket)
> @@ -1100,6 +1112,7 @@
>  			packet_send();
>  			buffer_consume(&c->extended, len);
>  			c->remote_window -= len;
> +			debug2("channel %d: sent ext data %d", c->self, len);
>  		}
>  	}
>  }
> 





More information about the openssh-unix-dev mailing list