4.6p1 chan_read_failed error
Darren Tucker
dtucker at zip.com.au
Sat Mar 24 22:49:03 EST 2007
On Fri, Mar 23, 2007 at 03:54:46PM -0700, Jim Stosick wrote:
> The 4.6p1 sshd is logging this error during remote commands or file
> transfers:
>
> error: channel 0: chan_read_failed for istate 3
>
> Platform is Solaris 8, 4.6p1 + OpenSSL 0.9.8d.
>
> The commands and transfers work correctly, so the error message appears
> to be spurious. The error message does not appear when processing logins.
>
> Otherwise 4.6p1 is running without any apparent problems. This error
> did not occur running 4.5p1.
[...]
I suspect this is related to the change for bug #52. You could try
reverting the following patch ("patch -p1 -R") and see if the error
messages stop.
Index: openssh/channels.c
diff -u openssh/channels.c:1.250 openssh/channels.c:1.251
--- openssh/channels.c:1.250 Fri Jan 5 16:30:16 2007
+++ openssh/channels.c Mon Jan 29 10:16:28 2007
@@ -1449,10 +1449,11 @@
int len;
if (c->rfd != -1 &&
- FD_ISSET(c->rfd, readset)) {
+ (c->detach_close || FD_ISSET(c->rfd, readset))) {
errno = 0;
len = read(c->rfd, buf, sizeof(buf));
- if (len < 0 && (errno == EINTR || errno == EAGAIN))
+ if (len < 0 && (errno == EINTR ||
+ (errno == EAGAIN && !(c->isatty && c->detach_close))))
return 1;
#ifndef PTY_ZEROREAD
if (len <= 0) {
@@ -1604,11 +1605,12 @@
c->local_consumed += len;
}
} else if (c->extended_usage == CHAN_EXTENDED_READ &&
- FD_ISSET(c->efd, readset)) {
+ (c->detach_close || FD_ISSET(c->efd, readset))) {
len = read(c->efd, buf, sizeof(buf));
debug2("channel %d: read %d from efd %d",
c->self, len, c->efd);
- if (len < 0 && (errno == EINTR || errno == EAGAIN))
+ if (len < 0 && (errno == EINTR ||
+ (errno == EAGAIN && !c->detach_close)))
return 1;
if (len <= 0) {
debug2("channel %d: closing read-efd %d",
Index: openssh/serverloop.c
diff -u openssh/serverloop.c:1.150 openssh/serverloop.c:1.151
--- openssh/serverloop.c:1.150 Tue Oct 24 03:02:41 2006
+++ openssh/serverloop.c Mon Jan 29 10:16:28 2007
@@ -280,6 +280,7 @@
struct timeval tv, *tvp;
int ret;
int client_alive_scheduled = 0;
+ int program_alive_scheduled = 0;
/*
* if using client_alive, set the max timeout accordingly,
@@ -317,6 +318,7 @@
* the client, try to get some more data from the program.
*/
if (packet_not_very_much_data_to_write()) {
+ program_alive_scheduled = child_terminated;
if (!fdout_eof)
FD_SET(fdout, *readsetp);
if (!fderr_eof)
@@ -362,8 +364,16 @@
memset(*writesetp, 0, *nallocp);
if (errno != EINTR)
error("select: %.100s", strerror(errno));
- } else if (ret == 0 && client_alive_scheduled)
- client_alive_check();
+ } else {
+ if (ret == 0 && client_alive_scheduled)
+ client_alive_check();
+ if (!compat20 && program_alive_scheduled && fdin_is_tty) {
+ if (!fdout_eof)
+ FD_SET(fdout, *readsetp);
+ if (!fderr_eof)
+ FD_SET(fderr, *readsetp);
+ }
+ }
notify_done(*readsetp);
}
@@ -407,7 +417,8 @@
if (!fdout_eof && FD_ISSET(fdout, readset)) {
errno = 0;
len = read(fdout, buf, sizeof(buf));
- if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
+ if (len < 0 && (errno == EINTR ||
+ (errno == EAGAIN && !child_terminated))) {
/* do nothing */
#ifndef PTY_ZEROREAD
} else if (len <= 0) {
@@ -425,7 +436,8 @@
if (!fderr_eof && FD_ISSET(fderr, readset)) {
errno = 0;
len = read(fderr, buf, sizeof(buf));
- if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
+ if (len < 0 && (errno == EINTR ||
+ (errno == EAGAIN && !child_terminated))) {
/* do nothing */
#ifndef PTY_ZEROREAD
} else if (len <= 0) {
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
More information about the openssh-unix-dev
mailing list