From 2da3d279e360bfb4ac470874d4b43b765b6596fa Mon Sep 17 00:00:00 2001 From: Nathan Straz Date: Thu, 19 Sep 2013 17:22:03 -0400 Subject: Handle stdin pipe closing on us If xiogen is flooding requests across qarsh and xdoio decides to stop, we need to handle that gracefully. Also, making the pipe non-blocking was not a good idea, xdoio gets the read error EAGAIN and stops there. --- qarsh.c | 6 ++++++ qarshd.c | 11 +++++++++-- qarshd@.service | 1 - 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/qarsh.c b/qarsh.c index 51a876b..2683591 100644 --- a/qarsh.c +++ b/qarsh.c @@ -395,6 +395,12 @@ run_remote_cmd(char *cmdline) fprintf(stderr, "ERROR: Received data allow for fd %d\n", qp->qp_dallow.qp_remfd); } + } else if (qp->qp_type == QP_RETURNCODE) { /* qarshd hit an error while writing to stdin */ + fprintf(stderr, "Remote command hit I/O error: %s\n", qp->qp_returncode.qp_strerror); + close(fileno(stdin)); + allowed_in = -1; + } else { + fprintf(stderr, "Unexpected packet type %s\n", qp_packet_type(qp->qp_type)); } qpfree(qp); nset--; diff --git a/qarshd.c b/qarshd.c index b911ef7..d686078 100644 --- a/qarshd.c +++ b/qarshd.c @@ -117,7 +117,7 @@ run_cmd(const char *cmd) pid_t pid; int pipefds[2], parentfds[3]; - pipe2(pipefds, O_NONBLOCK); + pipe(pipefds); childfds[0] = pipefds[1]; parentfds[0] = pipefds[0]; /* stdin */ pipe(pipefds); childfds[1] = pipefds[0]; parentfds[1] = pipefds[1]; /* stdout */ @@ -310,6 +310,7 @@ handle_qarsh() sa.sa_mask = sigmask; sa.sa_flags = SA_RESTART; sigaction(SIGCHLD, &sa, NULL); + signal(SIGPIPE, SIG_IGN); qp = make_qp_data_allow(0, QARSHD_BUFSIZE); send_packet(qoutfd, qp); @@ -416,7 +417,13 @@ handle_qarsh() if (nfd && FD_ISSET(childfds[0], &wfds)) { /* Child is ready for data on stdin */ nbytes = write(childfds[0], buf_in, z_in); - if (nbytes == z_in) { + if (nbytes == -1) { /* Don't try writing to the child again */ + close(childfds[0]); + childfds[0] = -1; + qp = make_qp_returncode(-1, errno, strerror(errno)); + send_packet(qoutfd, qp); + qpfree(qp); + } else if (nbytes == z_in) { z_in = 0; if (eof_in) { close(childfds[0]); diff --git a/qarshd@.service b/qarshd@.service index 875f924..408a6f5 100644 --- a/qarshd@.service +++ b/qarshd@.service @@ -5,4 +5,3 @@ Description=qarsh Per-Connection Server ExecStart=/usr/sbin/qarshd StandardInput=socket StandardError=journal -IgnoreSIGPIPE=no -- cgit