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