summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Straz <nstraz@redhat.com>2013-09-19 17:22:03 -0400
committerNathan Straz <nstraz@redhat.com>2013-09-19 17:22:03 -0400
commit2da3d279e360bfb4ac470874d4b43b765b6596fa (patch)
treeb712cb32baf01eddfa4bba8c3a090817aa6c38eb
parentfe8b924760c9ad8b81100a195f29b9c0eff54736 (diff)
downloadqarsh-2da3d279e360bfb4ac470874d4b43b765b6596fa.zip
qarsh-2da3d279e360bfb4ac470874d4b43b765b6596fa.tar.gz
qarsh-2da3d279e360bfb4ac470874d4b43b765b6596fa.tar.xz
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.
-rw-r--r--qarsh.c6
-rw-r--r--qarshd.c11
-rw-r--r--qarshd@.service1
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